summaryrefslogtreecommitdiff
path: root/i915
diff options
context:
space:
mode:
Diffstat (limited to 'i915')
-rw-r--r--i915/Makefile.am3
-rw-r--r--i915/i830_texblend.c1
-rw-r--r--i915/i830_texstate.c23
-rw-r--r--i915/i830_vtbl.c16
-rw-r--r--i915/i915_context.c5
-rw-r--r--i915/i915_context.h16
-rw-r--r--i915/i915_debug.c1
-rw-r--r--i915/i915_fragprog.c235
-rw-r--r--i915/i915_program.c31
-rw-r--r--i915/i915_program.h5
-rw-r--r--i915/i915_reg.h6
-rw-r--r--i915/i915_state.c32
-rw-r--r--i915/i915_texstate.c50
-rw-r--r--i915/i915_vtbl.c16
-rw-r--r--i915/intel_tris.c11
15 files changed, 355 insertions, 96 deletions
diff --git a/i915/Makefile.am b/i915/Makefile.am
index 451e9fd..c994f96 100644
--- a/i915/Makefile.am
+++ b/i915/Makefile.am
@@ -5,7 +5,7 @@ I915_CFLAGS = -I../shared -I../shared/server -DI915
i915_dri_la_LTLIBRARIES = i915_dri.la
i915_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) $(I915_CFLAGS)
i915_dri_la_LDFLAGS = -module -noprefix -avoid-version -lm -ldl \
- $(DRM_LIBS) -ldrm_intel $(DRI_LIBS)
+ $(DRM_LIBS) $(DRI_LIBS)
i915_dri_ladir = @libdir@/dri
i915_dri_la_SOURCES = \
i830_context.c \
@@ -20,7 +20,6 @@ i915_dri_la_SOURCES = \
../shared/intel_batchbuffer.c \
../shared/intel_clear.c \
../shared/intel_extensions.c \
- ../shared/intel_generatemipmap.c \
../shared/intel_mipmap_tree.c \
../shared/intel_tex_layout.c \
../shared/intel_tex_image.c \
diff --git a/i915/i830_texblend.c b/i915/i830_texblend.c
index 09f7f37..3f64be8 100644
--- a/i915/i830_texblend.c
+++ b/i915/i830_texblend.c
@@ -30,7 +30,6 @@
#include "main/mtypes.h"
#include "main/simple_list.h"
#include "main/enums.h"
-#include "main/texformat.h"
#include "main/texstore.h"
#include "main/mm.h"
diff --git a/i915/i830_texstate.c b/i915/i830_texstate.c
index 6f998fa..ce409b3 100644
--- a/i915/i830_texstate.c
+++ b/i915/i830_texstate.c
@@ -27,7 +27,6 @@
#include "main/mtypes.h"
#include "main/enums.h"
-#include "main/texformat.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
@@ -56,10 +55,9 @@ translate_texture_format(GLuint mesa_format, GLuint internal_format)
case MESA_FORMAT_ARGB4444:
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
case MESA_FORMAT_ARGB8888:
- if (internal_format == GL_RGB)
- return MAPSURF_32BIT | MT_32BIT_XRGB8888;
- else
- return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ case MESA_FORMAT_XRGB8888:
+ return MAPSURF_32BIT | MT_32BIT_XRGB8888;
case MESA_FORMAT_YCBCR_REV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case MESA_FORMAT_YCBCR:
@@ -160,13 +158,20 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
pitch = intelObj->pitchOverride;
} else {
+ GLuint dst_x, dst_y;
+
+ intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0,
+ &dst_x, &dst_y);
+
dri_bo_reference(intelObj->mt->region->buffer);
i830->state.tex_buffer[unit] = intelObj->mt->region->buffer;
- i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
- 0, intelObj->
- firstLevel);
+ /* XXX: This calculation is probably broken for tiled images with
+ * a non-page-aligned offset.
+ */
+ i830->state.tex_offset[unit] = (dst_x + dst_y * intelObj->mt->pitch) *
+ intelObj->mt->cpp;
- format = translate_texture_format(firstImage->TexFormat->MesaFormat,
+ format = translate_texture_format(firstImage->TexFormat,
firstImage->InternalFormat);
pitch = intelObj->mt->pitch * intelObj->mt->cpp;
}
diff --git a/i915/i830_vtbl.c b/i915/i830_vtbl.c
index 983f672..e8c8d5a 100644
--- a/i915/i830_vtbl.c
+++ b/i915/i830_vtbl.c
@@ -26,7 +26,6 @@
**************************************************************************/
#include "glapi/glapi.h"
-#include "main/texformat.h"
#include "i830_context.h"
#include "i830_reg.h"
@@ -646,8 +645,9 @@ i830_state_draw_region(struct intel_context *intel,
DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */
if (irb != NULL) {
- switch (irb->texformat->MesaFormat) {
+ switch (irb->Base.Format) {
case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_XRGB8888:
value |= DV_PF_8888;
break;
case MESA_FORMAT_RGB565:
@@ -661,7 +661,7 @@ i830_state_draw_region(struct intel_context *intel,
break;
default:
_mesa_problem(ctx, "Bad renderbuffer format: %d\n",
- irb->texformat->MesaFormat);
+ irb->Base.Format);
}
}
@@ -719,15 +719,6 @@ i830_new_batch(struct intel_context *intel)
assert(!intel->no_batch_wrap);
}
-
-
-static GLuint
-i830_flush_cmd(void)
-{
- return MI_FLUSH | FLUSH_MAP_CACHE;
-}
-
-
static void
i830_assert_not_dirty( struct intel_context *intel )
{
@@ -753,7 +744,6 @@ i830InitVtbl(struct i830_context *i830)
i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state;
i830->intel.vtbl.set_draw_region = i830_set_draw_region;
i830->intel.vtbl.update_texture_state = i830UpdateTextureState;
- i830->intel.vtbl.flush_cmd = i830_flush_cmd;
i830->intel.vtbl.render_start = i830_render_start;
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
diff --git a/i915/i915_context.c b/i915/i915_context.c
index 3ab7d68..7d4c7cf 100644
--- a/i915/i915_context.c
+++ b/i915/i915_context.c
@@ -40,6 +40,7 @@
#include "utils.h"
#include "i915_reg.h"
+#include "i915_program.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
@@ -80,6 +81,8 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
i915_update_stencil(ctx);
if (new_state & (_NEW_LIGHT))
i915_update_provoking_vertex(ctx);
+ if (new_state & (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))
+ i915_update_program(ctx);
}
@@ -139,7 +142,7 @@ i915CreateContext(const __GLcontextModes * mesaVis,
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
-
+ ctx->Const.MaxVarying = I915_TEX_UNITS;
/* Advertise the full hardware capabilities. The new memory
* manager should cope much better with overload situations:
diff --git a/i915/i915_context.h b/i915/i915_context.h
index 8de4a9d..25418d5 100644
--- a/i915/i915_context.h
+++ b/i915/i915_context.h
@@ -39,6 +39,7 @@
#define I915_FALLBACK_LOGICOP 0x20000
#define I915_FALLBACK_POLYGON_SMOOTH 0x40000
#define I915_FALLBACK_POINT_SMOOTH 0x80000
+#define I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN 0x100000
#define I915_UPLOAD_CTX 0x1
#define I915_UPLOAD_BUFFERS 0x2
@@ -121,10 +122,14 @@ enum {
#define I915_MAX_CONSTANT 32
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT))
+#define I915_MAX_INSN (I915_MAX_DECL_INSN + \
+ I915_MAX_TEX_INSN + \
+ I915_MAX_ALU_INSN)
-#define I915_PROGRAM_SIZE 192
-
-#define I915_MAX_INSN (I915_MAX_TEX_INSN+I915_MAX_ALU_INSN)
+/* Maximum size of the program packet, which matches the limits on
+ * decl, tex, and ALU instructions.
+ */
+#define I915_PROGRAM_SIZE (I915_MAX_INSN * 3 + 1)
/* Hardware version of a parsed fragment program. "Derived" from the
* mesa fragment_program struct.
@@ -154,8 +159,9 @@ struct i915_fragment_program
*/
GLcontext *ctx;
- GLuint declarations[I915_PROGRAM_SIZE];
- GLuint program[I915_PROGRAM_SIZE];
+ /* declarations contains the packet header. */
+ GLuint declarations[I915_MAX_DECL_INSN * 3 + 1];
+ GLuint program[(I915_MAX_TEX_INSN + I915_MAX_ALU_INSN) * 3];
GLfloat constant[I915_MAX_CONSTANT][4];
GLuint constant_flags[I915_MAX_CONSTANT];
diff --git a/i915/i915_debug.c b/i915/i915_debug.c
index f7bb7ea..fecfac3 100644
--- a/i915/i915_debug.c
+++ b/i915/i915_debug.c
@@ -806,6 +806,7 @@ static GLboolean i915_debug_packet( struct debug_stream *stream )
default:
return debug(stream, "", 0);
}
+ break;
default:
assert(0);
return 0;
diff --git a/i915/i915_fragprog.c b/i915/i915_fragprog.c
index 2db10c6..d9c6144 100644
--- a/i915/i915_fragprog.c
+++ b/i915/i915_fragprog.c
@@ -89,7 +89,8 @@ src_vector(struct i915_fragment_program *p,
*/
case PROGRAM_TEMPORARY:
if (source->Index >= I915_MAX_TEMPORARY) {
- i915_program_error(p, "Exceeded max temporary reg");
+ i915_program_error(p, "Exceeded max temporary reg: %d/%d",
+ source->Index, I915_MAX_TEMPORARY);
return 0;
}
src = UREG(REG_TYPE_R, source->Index);
@@ -121,10 +122,23 @@ src_vector(struct i915_fragment_program *p,
src = i915_emit_decl(p, REG_TYPE_T,
T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0),
D0_CHANNEL_ALL);
+ break;
+
+ case FRAG_ATTRIB_VAR0:
+ case FRAG_ATTRIB_VAR0 + 1:
+ case FRAG_ATTRIB_VAR0 + 2:
+ case FRAG_ATTRIB_VAR0 + 3:
+ case FRAG_ATTRIB_VAR0 + 4:
+ case FRAG_ATTRIB_VAR0 + 5:
+ case FRAG_ATTRIB_VAR0 + 6:
+ case FRAG_ATTRIB_VAR0 + 7:
+ src = i915_emit_decl(p, REG_TYPE_T,
+ T_TEX0 + (source->Index - FRAG_ATTRIB_VAR0),
+ D0_CHANNEL_ALL);
break;
default:
- i915_program_error(p, "Bad source->Index");
+ i915_program_error(p, "Bad source->Index: %d", source->Index);
return 0;
}
break;
@@ -146,6 +160,7 @@ src_vector(struct i915_fragment_program *p,
case PROGRAM_CONSTANT:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
+ case PROGRAM_UNIFORM:
src =
i915_emit_param4fv(p,
program->Base.Parameters->ParameterValues[source->
@@ -153,7 +168,7 @@ src_vector(struct i915_fragment_program *p,
break;
default:
- i915_program_error(p, "Bad source->File");
+ i915_program_error(p, "Bad source->File: %d", source->File);
return 0;
}
@@ -186,13 +201,14 @@ get_result_vector(struct i915_fragment_program *p,
p->depth_written = 1;
return UREG(REG_TYPE_OD, 0);
default:
- i915_program_error(p, "Bad inst->DstReg.Index");
+ i915_program_error(p, "Bad inst->DstReg.Index: %d",
+ inst->DstReg.Index);
return 0;
}
case PROGRAM_TEMPORARY:
return UREG(REG_TYPE_R, inst->DstReg.Index);
default:
- i915_program_error(p, "Bad inst->DstReg.File");
+ i915_program_error(p, "Bad inst->DstReg.File: %d", inst->DstReg.File);
return 0;
}
}
@@ -231,7 +247,7 @@ translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit)
case TEXTURE_CUBE_INDEX:
return D0_SAMPLE_TYPE_CUBE;
default:
- i915_program_error(p, "TexSrcBit");
+ i915_program_error(p, "TexSrcBit: %d", bit);
return 0;
}
}
@@ -351,7 +367,7 @@ upload_program(struct i915_fragment_program *p)
while (1) {
GLuint src0, src1, src2, flags;
- GLuint tmp = 0, consts0 = 0, consts1 = 0;
+ GLuint tmp = 0, dst, consts0 = 0, consts1 = 0;
switch (inst->Opcode) {
case OPCODE_ABS:
@@ -503,6 +519,10 @@ upload_program(struct i915_fragment_program *p)
EMIT_1ARG_ARITH(A0_FLR);
break;
+ case OPCODE_TRUNC:
+ EMIT_1ARG_ARITH(A0_TRC);
+ break;
+
case OPCODE_FRC:
EMIT_1ARG_ARITH(A0_FRC);
break;
@@ -516,6 +536,22 @@ upload_program(struct i915_fragment_program *p)
0, src0, T0_TEXKILL);
break;
+ case OPCODE_KIL_NV:
+ if (inst->DstReg.CondMask == COND_TR) {
+ tmp = i915_get_utemp(p);
+
+ i915_emit_texld(p, get_live_regs(p, inst),
+ tmp, A0_DEST_CHANNEL_ALL,
+ 0, /* use a dummy dest reg */
+ swizzle(tmp, ONE, ONE, ONE, ONE), /* always */
+ T0_TEXKILL);
+ } else {
+ p->error = 1;
+ i915_program_error(p, "Unsupported KIL_NV condition code: %d",
+ inst->DstReg.CondMask);
+ }
+ break;
+
case OPCODE_LG2:
src0 = src_vector(p, &inst->SrcReg[0], program);
@@ -615,6 +651,20 @@ upload_program(struct i915_fragment_program *p)
EMIT_2ARG_ARITH(A0_MUL);
break;
+ case OPCODE_NOISE1:
+ case OPCODE_NOISE2:
+ case OPCODE_NOISE3:
+ case OPCODE_NOISE4:
+ /* Don't implement noise because we just don't have the instructions
+ * to spare. We aren't the first vendor to do so.
+ */
+ i915_program_error(p, "Stubbed-out noise functions");
+ i915_emit_arith(p,
+ A0_MOV,
+ get_result_vector(p, inst),
+ get_result_flags(inst), 0,
+ swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0);
+
case OPCODE_POW:
src0 = src_vector(p, &inst->SrcReg[0], program);
src1 = src_vector(p, &inst->SrcReg[1], program);
@@ -721,9 +771,38 @@ upload_program(struct i915_fragment_program *p)
}
break;
- case OPCODE_SGE:
- EMIT_2ARG_ARITH(A0_SGE);
- break;
+ case OPCODE_SEQ:
+ tmp = i915_get_utemp(p);
+ flags = get_result_flags(inst);
+ dst = get_result_vector(p, inst);
+
+ /* dst = src1 >= src2 */
+ i915_emit_arith(p,
+ A0_SGE,
+ dst,
+ flags, 0,
+ src_vector(p, &inst->SrcReg[0], program),
+ src_vector(p, &inst->SrcReg[1], program),
+ 0);
+ /* tmp = src1 <= src2 */
+ i915_emit_arith(p,
+ A0_SGE,
+ tmp,
+ flags, 0,
+ negate(src_vector(p, &inst->SrcReg[0], program),
+ 1, 1, 1, 1),
+ negate(src_vector(p, &inst->SrcReg[1], program),
+ 1, 1, 1, 1),
+ 0);
+ /* dst = tmp && dst */
+ i915_emit_arith(p,
+ A0_MUL,
+ dst,
+ flags, 0,
+ dst,
+ tmp,
+ 0);
+ break;
case OPCODE_SIN:
src0 = src_vector(p, &inst->SrcReg[0], program);
@@ -809,10 +888,71 @@ upload_program(struct i915_fragment_program *p)
break;
+ case OPCODE_SGE:
+ EMIT_2ARG_ARITH(A0_SGE);
+ break;
+
+ case OPCODE_SGT:
+ i915_emit_arith(p,
+ A0_SLT,
+ get_result_vector( p, inst ),
+ get_result_flags( inst ), 0,
+ negate(src_vector( p, &inst->SrcReg[0], program),
+ 1, 1, 1, 1),
+ negate(src_vector( p, &inst->SrcReg[1], program),
+ 1, 1, 1, 1),
+ 0);
+ break;
+
+ case OPCODE_SLE:
+ i915_emit_arith(p,
+ A0_SGE,
+ get_result_vector( p, inst ),
+ get_result_flags( inst ), 0,
+ negate(src_vector( p, &inst->SrcReg[0], program),
+ 1, 1, 1, 1),
+ negate(src_vector( p, &inst->SrcReg[1], program),
+ 1, 1, 1, 1),
+ 0);
+ break;
+
case OPCODE_SLT:
EMIT_2ARG_ARITH(A0_SLT);
break;
+ case OPCODE_SNE:
+ tmp = i915_get_utemp(p);
+ flags = get_result_flags(inst);
+ dst = get_result_vector(p, inst);
+
+ /* dst = src1 < src2 */
+ i915_emit_arith(p,
+ A0_SLT,
+ dst,
+ flags, 0,
+ src_vector(p, &inst->SrcReg[0], program),
+ src_vector(p, &inst->SrcReg[1], program),
+ 0);
+ /* tmp = src1 > src2 */
+ i915_emit_arith(p,
+ A0_SLT,
+ tmp,
+ flags, 0,
+ negate(src_vector(p, &inst->SrcReg[0], program),
+ 1, 1, 1, 1),
+ negate(src_vector(p, &inst->SrcReg[1], program),
+ 1, 1, 1, 1),
+ 0);
+ /* dst = tmp || dst */
+ i915_emit_arith(p,
+ A0_ADD,
+ dst,
+ flags | A0_DEST_SATURATE, 0,
+ dst,
+ tmp,
+ 0);
+ break;
+
case OPCODE_SUB:
src0 = src_vector(p, &inst->SrcReg[0], program);
src1 = src_vector(p, &inst->SrcReg[1], program);
@@ -869,8 +1009,39 @@ upload_program(struct i915_fragment_program *p)
case OPCODE_END:
return;
+ case OPCODE_BGNLOOP:
+ case OPCODE_BGNSUB:
+ case OPCODE_BRA:
+ case OPCODE_BRK:
+ case OPCODE_CAL:
+ case OPCODE_CONT:
+ case OPCODE_DDX:
+ case OPCODE_DDY:
+ case OPCODE_ELSE:
+ case OPCODE_ENDIF:
+ case OPCODE_ENDLOOP:
+ case OPCODE_ENDSUB:
+ case OPCODE_IF:
+ case OPCODE_RET:
+ p->error = 1;
+ i915_program_error(p, "Unsupported opcode: %s",
+ _mesa_opcode_string(inst->Opcode));
+ return;
+
+ case OPCODE_EXP:
+ case OPCODE_LOG:
+ /* These opcodes are claimed as GLSL, NV_vp, and ARB_vp in
+ * prog_instruction.h, but apparently GLSL doesn't ever emit them.
+ * Instead, it translates to EX2 or LG2.
+ */
+ case OPCODE_TXD:
+ case OPCODE_TXL:
+ /* These opcodes are claimed by GLSL in prog_instruction.h, but
+ * only NV_vp/fp appears to emit them.
+ */
default:
- i915_program_error(p, "bad opcode");
+ i915_program_error(p, "bad opcode: %s",
+ _mesa_opcode_string(inst->Opcode));
return;
}
@@ -906,7 +1077,7 @@ check_wpos(struct i915_fragment_program *p)
p->wpos_tex = -1;
for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
- if (inputs & FRAG_BIT_TEX(i))
+ if (inputs & (FRAG_BIT_TEX(i) | FRAG_BIT_VAR(i)))
continue;
else if (inputs & FRAG_BIT_WPOS) {
p->wpos_tex = i;
@@ -1055,6 +1226,28 @@ i915ProgramStringNotify(GLcontext * ctx,
_tnl_program_string(ctx, target, prog);
}
+void
+i915_update_program(GLcontext *ctx)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct i915_context *i915 = i915_context(&intel->ctx);
+ struct i915_fragment_program *fp =
+ (struct i915_fragment_program *) ctx->FragmentProgram._Current;
+
+ if (i915->current_program != fp) {
+ if (i915->current_program) {
+ i915->current_program->on_hardware = 0;
+ i915->current_program->params_uptodate = 0;
+ }
+
+ i915->current_program = fp;
+ }
+
+ if (!fp->translated)
+ translate_program(fp);
+
+ FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, fp->error);
+}
void
i915ValidateFragmentProgram(struct i915_context *i915)
@@ -1072,16 +1265,6 @@ i915ValidateFragmentProgram(struct i915_context *i915)
GLuint s2 = S2_TEXCOORD_NONE;
int i, offset = 0;
- if (i915->current_program != p) {
- if (i915->current_program) {
- i915->current_program->on_hardware = 0;
- i915->current_program->params_uptodate = 0;
- }
-
- i915->current_program = p;
- }
-
-
/* Important:
*/
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
@@ -1125,6 +1308,14 @@ i915ValidateFragmentProgram(struct i915_context *i915)
EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
}
+ else if (inputsRead & FRAG_BIT_VAR(i)) {
+ 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));
+
+ EMIT_ATTR(_TNL_ATTRIB_GENERIC0 + i, EMIT_SZ(sz), 0, sz * 4);
+ }
else if (i == p->wpos_tex) {
/* If WPOS is required, duplicate the XYZ position data in an
diff --git a/i915/i915_program.c b/i915/i915_program.c
index e87700f..e7908bd 100644
--- a/i915/i915_program.c
+++ b/i915/i915_program.c
@@ -130,6 +130,7 @@ i915_emit_decl(struct i915_fragment_program *p,
*(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
*(p->decl++) = D1_MBZ;
*(p->decl++) = D2_MBZ;
+ assert(p->decl <= p->declarations + ARRAY_SIZE(p->declarations));
p->nr_decl_insn++;
return reg;
@@ -186,6 +187,11 @@ i915_emit_arith(struct i915_fragment_program * p,
p->utemp_flag = old_utemp_flag; /* restore */
}
+ if (p->csr >= p->program + ARRAY_SIZE(p->program)) {
+ i915_program_error(p, "Program contains too many instructions");
+ return UREG_BAD;
+ }
+
*(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
*(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
*(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
@@ -270,6 +276,11 @@ GLuint i915_emit_texld( struct i915_fragment_program *p,
p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
p->nr_tex_indirect++;
+ if (p->csr >= p->program + ARRAY_SIZE(p->program)) {
+ i915_program_error(p, "Program contains too many instructions");
+ return UREG_BAD;
+ }
+
*(p->csr++) = (op |
T0_DEST( dest ) |
T0_SAMPLER( sampler ));
@@ -424,12 +435,21 @@ i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values)
return 0;
}
-
-
+/* Warning the user about program errors seems to be quite valuable, from
+ * our bug reports. It unfortunately means piglit reporting errors
+ * when we fall back to software due to an unsupportable program, though.
+ */
void
-i915_program_error(struct i915_fragment_program *p, const char *msg)
+i915_program_error(struct i915_fragment_program *p, const char *fmt, ...)
{
- _mesa_problem(NULL, "i915_program_error: %s", msg);
+ va_list args;
+
+ fprintf(stderr, "i915_program_error: ");
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ fprintf(stderr, "\n");
p->error = 1;
}
@@ -511,7 +531,8 @@ i915_upload_program(struct i915_context *i915,
GLuint program_size = p->csr - p->program;
GLuint decl_size = p->decl - p->declarations;
- FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error);
+ if (p->error)
+ return;
/* Could just go straight to the batchbuffer from here:
*/
diff --git a/i915/i915_program.h b/i915/i915_program.h
index 14a3f08..0d17d04 100644
--- a/i915/i915_program.h
+++ b/i915/i915_program.h
@@ -145,7 +145,7 @@ extern GLuint i915_emit_param4fv(struct i915_fragment_program *p,
const GLfloat * values);
extern void i915_program_error(struct i915_fragment_program *p,
- const char *msg);
+ const char *fmt, ...);
extern void i915_init_program(struct i915_context *i915,
struct i915_fragment_program *p);
@@ -155,7 +155,6 @@ extern void i915_upload_program(struct i915_context *i915,
extern void i915_fini_program(struct i915_fragment_program *p);
-
-
+extern void i915_update_program(GLcontext *ctx);
#endif
diff --git a/i915/i915_reg.h b/i915/i915_reg.h
index b5fa7fd..7f31ff6 100644
--- a/i915/i915_reg.h
+++ b/i915/i915_reg.h
@@ -626,9 +626,9 @@
#define MT_32BIT_AWVU2101010 (0xA<<3)
#define MT_32BIT_GR1616 (0xB<<3)
#define MT_32BIT_VU1616 (0xC<<3)
-#define MT_32BIT_xI824 (0xD<<3)
-#define MT_32BIT_xA824 (0xE<<3)
-#define MT_32BIT_xL824 (0xF<<3)
+#define MT_32BIT_x8I24 (0xD<<3)
+#define MT_32BIT_x8L24 (0xE<<3)
+#define MT_32BIT_x8A24 (0xF<<3)
#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */
#define MT_422_YCRCB_NORMAL (1<<3)
#define MT_422_YCRCB_SWAPUV (2<<3)
diff --git a/i915/i915_state.c b/i915/i915_state.c
index b60efea..cc98d12 100644
--- a/i915/i915_state.c
+++ b/i915/i915_state.c
@@ -585,7 +585,7 @@ i915PointSize(GLcontext * ctx, GLfloat size)
{
struct i915_context *i915 = I915_CONTEXT(ctx);
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
- GLint point_size = (int) size;
+ GLint point_size = (int) round(size);
DBG("%s\n", __FUNCTION__);
@@ -599,6 +599,24 @@ i915PointSize(GLcontext * ctx, GLfloat size)
}
+static void
+i915PointParameterfv(GLcontext * ctx, GLenum pname, const GLfloat *params)
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ /* This could be supported, but it would require modifying the fragment
+ * program to invert the y component of the texture coordinate by
+ * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction.
+ */
+ FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN,
+ (params[0] != GL_UPPER_LEFT));
+ break;
+ }
+}
+
+
/* =============================================================
* Color masks
*/
@@ -939,6 +957,17 @@ i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
case GL_POLYGON_SMOOTH:
break;
+ case GL_POINT_SPRITE:
+ /* This state change is handled in i915_reduced_primitive_state because
+ * the hardware bit should only be set when rendering points.
+ */
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+ if (state)
+ i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE;
+ else
+ i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE;
+ break;
+
case GL_POINT_SMOOTH:
break;
@@ -1108,6 +1137,7 @@ i915InitStateFunctions(struct dd_function_table *functions)
functions->LineWidth = i915LineWidth;
functions->LogicOpcode = i915LogicOp;
functions->PointSize = i915PointSize;
+ functions->PointParameterfv = i915PointParameterfv;
functions->PolygonStipple = i915PolygonStipple;
functions->Scissor = i915Scissor;
functions->ShadeModel = i915ShadeModel;
diff --git a/i915/i915_texstate.c b/i915/i915_texstate.c
index 32d4b30..de25848 100644
--- a/i915/i915_texstate.c
+++ b/i915/i915_texstate.c
@@ -27,7 +27,7 @@
#include "main/mtypes.h"
#include "main/enums.h"
-#include "main/texformat.h"
+#include "main/macros.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
@@ -37,7 +37,7 @@
static GLuint
-translate_texture_format(GLuint mesa_format, GLuint internal_format,
+translate_texture_format(gl_format mesa_format, GLuint internal_format,
GLenum DepthMode)
{
switch (mesa_format) {
@@ -56,10 +56,9 @@ translate_texture_format(GLuint mesa_format, GLuint internal_format,
case MESA_FORMAT_ARGB4444:
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
case MESA_FORMAT_ARGB8888:
- if (internal_format == GL_RGB)
- return MAPSURF_32BIT | MT_32BIT_XRGB8888;
- else
- return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ case MESA_FORMAT_XRGB8888:
+ return MAPSURF_32BIT | MT_32BIT_XRGB8888;
case MESA_FORMAT_YCBCR_REV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case MESA_FORMAT_YCBCR:
@@ -82,7 +81,12 @@ translate_texture_format(GLuint mesa_format, GLuint internal_format,
case MESA_FORMAT_RGBA_DXT5:
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
case MESA_FORMAT_S8_Z24:
- return (MAPSURF_32BIT | MT_32BIT_xI824);
+ if (DepthMode == GL_ALPHA)
+ return (MAPSURF_32BIT | MT_32BIT_x8A24);
+ else if (DepthMode == GL_INTENSITY)
+ return (MAPSURF_32BIT | MT_32BIT_x8I24);
+ else
+ return (MAPSURF_32BIT | MT_32BIT_x8L24);
default:
fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format);
abort();
@@ -134,6 +138,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
GLuint *state = i915->state.Tex[unit], format, pitch;
GLint lodbias, aniso = 0;
GLubyte border[4];
+ GLfloat maxlod;
memset(state, 0, sizeof(state));
@@ -173,11 +178,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
} else {
dri_bo_reference(intelObj->mt->region->buffer);
i915->state.tex_buffer[unit] = intelObj->mt->region->buffer;
- i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
- 0, intelObj->
- firstLevel);
+ i915->state.tex_offset[unit] = 0; /* Always the origin of the miptree */
- format = translate_texture_format(firstImage->TexFormat->MesaFormat,
+ format = translate_texture_format(firstImage->TexFormat,
firstImage->InternalFormat,
tObj->DepthMode);
pitch = intelObj->mt->pitch * intelObj->mt->cpp;
@@ -193,11 +196,15 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
state[I915_TEXREG_MS3] |= MS3_TILE_WALK;
}
+ /* We get one field with fraction bits to cover the maximum addressable (smallest
+ * resolution) LOD. Use it to cover both MAX_LEVEL and MAX_LOD.
+ */
+ maxlod = MIN2(tObj->MaxLod, tObj->MaxLevel - tObj->BaseLevel);
state[I915_TEXREG_MS4] =
- ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
- ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) <<
- MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) <<
- MS4_VOLUME_DEPTH_SHIFT));
+ ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
+ MS4_CUBE_FACE_ENA_MASK |
+ (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
+ ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
{
@@ -263,8 +270,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
/* YUV conversion:
*/
- if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR ||
- firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV)
+ if (firstImage->TexFormat == MESA_FORMAT_YCBCR ||
+ firstImage->TexFormat == MESA_FORMAT_YCBCR_REV)
state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION;
/* Shadow:
@@ -293,6 +300,12 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
GLenum wt = tObj->WrapT;
GLenum wr = tObj->WrapR;
+ /* We program 1D textures as 2D textures, so the 2D texcoord could
+ * result in sampling border values if we don't set the T wrap to
+ * repeat.
+ */
+ if (tObj->Target == GL_TEXTURE_1D)
+ wt = GL_REPEAT;
/* 3D textures don't seem to respect the border color.
* Fallback if there's ever a danger that they might refer to
@@ -327,6 +340,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
(translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
+ state[I915_TEXREG_SS3] |= (U_FIXED(CLAMP(tObj->MinLod, 0.0, 11.0), 4) <<
+ SS3_MIN_LOD_SHIFT);
+
}
/* convert border color from float to ubyte */
diff --git a/i915/i915_vtbl.c b/i915/i915_vtbl.c
index 9a723d3..ff97e5a 100644
--- a/i915/i915_vtbl.c
+++ b/i915/i915_vtbl.c
@@ -32,7 +32,6 @@
#include "main/imports.h"
#include "main/macros.h"
#include "main/colormac.h"
-#include "main/texformat.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
@@ -54,8 +53,7 @@ i915_render_prevalidate(struct intel_context *intel)
{
struct i915_context *i915 = i915_context(&intel->ctx);
- if (!intel->Fallback)
- i915ValidateFragmentProgram(i915);
+ i915ValidateFragmentProgram(i915);
}
static void
@@ -589,8 +587,9 @@ i915_state_draw_region(struct intel_context *intel,
DSTORG_VERT_BIAS(0x8) | /* .5 */
LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL);
if (irb != NULL) {
- switch (irb->texformat->MesaFormat) {
+ switch (irb->Base.Format) {
case MESA_FORMAT_ARGB8888:
+ case MESA_FORMAT_XRGB8888:
value |= DV_PF_8888;
break;
case MESA_FORMAT_RGB565:
@@ -604,7 +603,7 @@ i915_state_draw_region(struct intel_context *intel,
break;
default:
_mesa_problem(ctx, "Bad renderbuffer format: %d\n",
- irb->texformat->MesaFormat);
+ irb->Base.Format);
}
}
@@ -673,12 +672,6 @@ i915_new_batch(struct intel_context *intel)
assert(!intel->no_batch_wrap);
}
-static GLuint
-i915_flush_cmd(void)
-{
- return MI_FLUSH | FLUSH_MAP_CACHE;
-}
-
static void
i915_assert_not_dirty( struct intel_context *intel )
{
@@ -700,7 +693,6 @@ i915InitVtbl(struct i915_context *i915)
i915->intel.vtbl.render_prevalidate = i915_render_prevalidate;
i915->intel.vtbl.set_draw_region = i915_set_draw_region;
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
- i915->intel.vtbl.flush_cmd = i915_flush_cmd;
i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty;
i915->intel.vtbl.finish_batch = intel_finish_vb;
}
diff --git a/i915/intel_tris.c b/i915/intel_tris.c
index a905455..bc527aa 100644
--- a/i915/intel_tris.c
+++ b/i915/intel_tris.c
@@ -1076,7 +1076,9 @@ intelRunPipeline(GLcontext * ctx)
intel->NewGLState = 0;
}
+ intel_map_vertex_shader_textures(ctx);
_tnl_run_pipeline(ctx);
+ intel_unmap_vertex_shader_textures(ctx);
_mesa_unlock_context_textures(ctx);
}
@@ -1086,6 +1088,7 @@ intelRenderStart(GLcontext * ctx)
{
struct intel_context *intel = intel_context(ctx);
+ intel_check_front_buffer_rendering(intel);
intel->vtbl.render_start(intel_context(ctx));
intel->vtbl.emit_state(intel);
}
@@ -1194,12 +1197,16 @@ getFallbackString(GLuint bit)
+/**
+ * Enable/disable a fallback flag.
+ * \param bit one of INTEL_FALLBACK_x flags.
+ */
void
-intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode)
+intelFallback(struct intel_context *intel, GLbitfield bit, GLboolean mode)
{
GLcontext *ctx = &intel->ctx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint oldfallback = intel->Fallback;
+ const GLbitfield oldfallback = intel->Fallback;
if (mode) {
intel->Fallback |= bit;