diff options
Diffstat (limited to 'src/mesa/drivers/dri/i915')
-rw-r--r-- | src/mesa/drivers/dri/i915/Makefile | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_context.c | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_context.h | 15 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_fragprog.c | 235 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.c | 31 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_vtbl.c | 3 | ||||
l--------- | src/mesa/drivers/dri/i915/intel_generatemipmap.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_tris.c | 2 |
9 files changed, 258 insertions, 40 deletions
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index 9d049dea8fe..393312e7328 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -19,7 +19,6 @@ DRIVER_SOURCES = \ intel_batchbuffer.c \ intel_clear.c \ intel_extensions.c \ - intel_generatemipmap.c \ intel_mipmap_tree.c \ intel_tex_layout.c \ intel_tex_image.c \ diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 3ab7d682ee7..7d4c7cfbabb 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 8de4a9d0d36..082d6144425 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -121,10 +121,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 +158,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/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 2db10c60e99..d9c61446f52 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index e87700f8e0a..e7908bd48fc 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_program.h b/src/mesa/drivers/dri/i915/i915_program.h index 14a3f08801f..0d17d048653 100644 --- a/src/mesa/drivers/dri/i915/i915_program.h +++ b/src/mesa/drivers/dri/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/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 9a723d3cd73..9e2523932f1 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -54,8 +54,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 diff --git a/src/mesa/drivers/dri/i915/intel_generatemipmap.c b/src/mesa/drivers/dri/i915/intel_generatemipmap.c deleted file mode 120000 index 4c6b37ada01..00000000000 --- a/src/mesa/drivers/dri/i915/intel_generatemipmap.c +++ /dev/null @@ -1 +0,0 @@ -../intel/intel_generatemipmap.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index a905455342d..0641e6df9d7 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/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); } |