diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_program.c | 34 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_tex_layout.c | 80 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vs_emit.c | 90 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 8 |
4 files changed, 146 insertions, 66 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 1fd957b3ad6..41a1f438df4 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -34,6 +34,7 @@ #include "shader/prog_parameter.h" #include "shader/program.h" #include "shader/programopt.h" +#include "shader/shader_api.h" #include "tnl/tnl.h" #include "brw_context.h" @@ -119,12 +120,28 @@ static GLboolean brwIsProgramNative( GLcontext *ctx, return GL_TRUE; } +static void +shader_error(GLcontext *ctx, struct gl_program *prog, const char *msg) +{ + struct gl_shader_program *shader; + + shader = _mesa_lookup_shader_program(ctx, prog->Id); + + if (shader) { + if (shader->InfoLog) { + free(shader->InfoLog); + } + shader->InfoLog = _mesa_strdup(msg); + shader->LinkStatus = GL_FALSE; + } +} static GLboolean brwProgramStringNotify( GLcontext *ctx, GLenum target, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); + int i; if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; @@ -160,7 +177,22 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx, _tnl_program_string(ctx, target, prog); } - /* XXX check if program is legal, within limits */ + /* Reject programs with subroutines, which are totally broken at the moment + * (all program flows return when any program flow returns, and + * the VS also hangs if a function call calls a function. + * + * See piglit glsl-{vs,fs}-functions-[23] tests. + */ + for (i = 0; i < prog->NumInstructions; i++) { + if (prog->Instructions[i].Opcode == OPCODE_CAL) { + shader_error(ctx, prog, + "i965 driver doesn't yet support uninlined function " + "calls. Move to using a single return statement at " + "the end of the function to work around it."); + return GL_FALSE; + } + } + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 9a215ab8a4d..768ccfd79c4 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -49,74 +49,30 @@ GLboolean brw_miptree_layout(struct intel_context *intel, switch (mt->target) { case GL_TEXTURE_CUBE_MAP: if (intel->gen == 5) { - GLuint align_h = 2, align_w = 4; + GLuint align_h = 2; GLuint level; - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; GLuint qpitch = 0; - GLuint y_pitch = 0; + int h0, h1, q; - mt->total_width = mt->width0; - intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h); - y_pitch = ALIGN(height, align_h); + /* On Ironlake, cube maps are finally represented as just a series + * of MIPLAYOUT_BELOW 2D textures (like 2D texture arrays), separated + * by a pitch of qpitch rows, where qpitch is defined by the equation + * given in Volume 1 of the BSpec. + */ + h0 = ALIGN(mt->height0, align_h); + h1 = ALIGN(minify(h0), align_h); + qpitch = (h0 + h1 + 11 * align_h); + if (mt->compressed) + qpitch /= 4; - if (mt->compressed) { - mt->total_width = ALIGN(mt->width0, align_w); - } - - if (mt->first_level != mt->last_level) { - GLuint mip1_width; - - if (mt->compressed) { - mip1_width = ALIGN(minify(mt->width0), align_w) - + ALIGN(minify(minify(mt->width0)), align_w); - } else { - mip1_width = ALIGN(minify(mt->width0), align_w) - + minify(minify(mt->width0)); - } - - if (mip1_width > mt->total_width) { - mt->total_width = mip1_width; - } - } - - if (mt->compressed) { - qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4; - mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6; - } else { - qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h); - mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6; - } + i945_miptree_layout_2d(intel, mt, tiling, 6); for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint img_height; - GLuint nr_images = 6; - GLuint q = 0; - - intel_miptree_set_level_info(mt, level, nr_images, x, y, width, - height, 1); - - for (q = 0; q < nr_images; q++) - intel_miptree_set_image_offset(mt, level, q, - x, y + q * qpitch); - - if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = ALIGN(height, align_h); - - if (level == mt->first_level + 1) { - x += ALIGN(width, align_w); - } - else { - y += img_height; - } - - width = minify(width); - height = minify(height); + for (q = 0; q < 6; q++) { + intel_miptree_set_image_offset(mt, level, q, 0, q * qpitch); + } } + mt->total_height = qpitch * 6; break; } @@ -206,7 +162,7 @@ GLboolean brw_miptree_layout(struct intel_context *intel, } default: - i945_miptree_layout_2d(intel, mt, tiling); + i945_miptree_layout_2d(intel, mt, tiling, 1); break; } DBG("%s: %dx%dx%d\n", __FUNCTION__, diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index eeb3f366a41..dc6ab81c4ac 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -37,6 +37,43 @@ #include "brw_context.h" #include "brw_vs.h" +/* Return the SrcReg index of the channels that can be immediate float operands + * instead of usage of PROGRAM_CONSTANT values through push/pull. + */ +static GLboolean +brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg) +{ + int opcode_array[] = { + [OPCODE_ADD] = 2, + [OPCODE_CMP] = 3, + [OPCODE_DP3] = 2, + [OPCODE_DP4] = 2, + [OPCODE_DPH] = 2, + [OPCODE_MAX] = 2, + [OPCODE_MIN] = 2, + [OPCODE_MUL] = 2, + [OPCODE_SEQ] = 2, + [OPCODE_SGE] = 2, + [OPCODE_SGT] = 2, + [OPCODE_SLE] = 2, + [OPCODE_SLT] = 2, + [OPCODE_SNE] = 2, + [OPCODE_XPD] = 2, + }; + + /* These opcodes get broken down in a way that allow two + * args to be immediates. + */ + if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) { + if (arg == 1 || arg == 2) + return GL_TRUE; + } + + if (opcode > ARRAY_SIZE(opcode_array)) + return GL_FALSE; + + return arg == opcode_array[opcode] - 1; +} static struct brw_reg get_tmp( struct brw_vs_compile *c ) { @@ -453,8 +490,8 @@ static void emit_max( struct brw_compile *p, struct brw_reg arg0, struct brw_reg arg1 ) { - brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1); - brw_SEL(p, dst, arg1, arg0); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1); + brw_SEL(p, dst, arg0, arg1); brw_set_predicate_control(p, BRW_PREDICATE_NONE); } @@ -983,6 +1020,55 @@ get_src_reg( struct brw_vs_compile *c, const GLint index = inst->SrcReg[argIndex].Index; const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr; + if (brw_vs_arg_can_be_immediate(inst->Opcode, argIndex)) { + const struct prog_src_register *src = &inst->SrcReg[argIndex]; + + if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ZERO, + SWIZZLE_ZERO, + SWIZZLE_ZERO, + SWIZZLE_ZERO)) { + return brw_imm_f(0.0f); + } else if (src->Swizzle == MAKE_SWIZZLE4(SWIZZLE_ONE, + SWIZZLE_ONE, + SWIZZLE_ONE, + SWIZZLE_ONE)) { + if (src->Negate) + return brw_imm_f(-1.0F); + else + return brw_imm_f(1.0F); + } else if (src->File == PROGRAM_CONSTANT) { + const struct gl_program_parameter_list *params; + float f; + int component = -1; + + switch (src->Swizzle) { + case SWIZZLE_XXXX: + component = 0; + break; + case SWIZZLE_YYYY: + component = 1; + break; + case SWIZZLE_ZZZZ: + component = 2; + break; + case SWIZZLE_WWWW: + component = 3; + break; + } + + if (component >= 0) { + params = c->vp->program.Base.Parameters; + f = params->ParameterValues[src->Index][component]; + + if (src->Abs) + f = fabs(f); + if (src->Negate) + f = -f; + return brw_imm_f(f); + } + } + } + switch (file) { case PROGRAM_TEMPORARY: case PROGRAM_INPUT: diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index d7650af3d9d..1582ff1ab65 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -228,6 +228,8 @@ brw_wm_sampler_populate_key(struct brw_context *brw, { GLcontext *ctx = &brw->intel.ctx; int unit; + char *last_entry_end = ((char*)&key->sampler_count) + + sizeof(key->sampler_count); key->sampler_count = 0; @@ -240,7 +242,9 @@ brw_wm_sampler_populate_key(struct brw_context *brw, struct gl_texture_image *firstImage = texObj->Image[0][intelObj->firstLevel]; - memset(entry, 0, sizeof(*entry)); + memset(last_entry_end, 0, + (char*)entry - last_entry_end + sizeof(*entry)); + last_entry_end = ((char*)entry) + sizeof(*entry); entry->tex_target = texObj->Target; @@ -280,6 +284,8 @@ brw_wm_sampler_populate_key(struct brw_context *brw, key->sampler_count = unit + 1; } } + struct wm_sampler_entry *entry = &key->sampler[key->sampler_count]; + memset(last_entry_end, 0, (char*)entry - last_entry_end); } /* All samplers must be uploaded in a single contiguous array, which |