diff options
Diffstat (limited to 'src/mesa/drivers/dri/i915')
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_reg.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_state.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_texstate.c | 31 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i830_vtbl.c | 65 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_context.c | 28 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_context.h | 37 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_fragprog.c | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_program.c | 51 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_reg.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_state.c | 290 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_texstate.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_vtbl.c | 89 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_render.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_tris.c | 92 |
14 files changed, 480 insertions, 300 deletions
diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h index ae1317029a..99ee1bb4e9 100644 --- a/src/mesa/drivers/dri/i915/i830_reg.h +++ b/src/mesa/drivers/dri/i915/i830_reg.h @@ -585,6 +585,8 @@ #define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) #define TM0S2_OUTPUT_CHAN_SHIFT 10 #define TM0S2_OUTPUT_CHAN_MASK (3<<10) +#define TM0S2_BASE_MIP_LEVEL_SHIFT 1 +#define TM0S2_LOD_PRECLAMP (1 << 0) #define TM0S3_MIP_FILTER_MASK (0x3<<30) #define TM0S3_MIP_FILTER_SHIFT 30 @@ -605,6 +607,8 @@ #define TM0S3_MAX_MIP_MASK (0xff<<9) #define TM0S3_MIN_MIP_SHIFT 3 #define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_MIN_MIP_SHIFT_830 5 +#define TM0S3_MIN_MIP_MASK_830 (0x3f<<5) #define TM0S3_KILL_PIXEL (1<<2) #define TM0S3_KEYED_FILTER (1<<1) #define TM0S3_CHROMA_KEY (1<<0) diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index 147192adc7..9fecab10db 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -31,6 +31,7 @@ #include "main/macros.h" #include "main/enums.h" #include "main/dd.h" +#include "main/state.h" #include "texmem.h" @@ -234,7 +235,7 @@ i830EvalLogicOpBlendState(struct gl_context * ctx) I830_STATECHANGE(i830, I830_UPLOAD_CTX); - if (RGBA_LOGICOP_ENABLED(ctx)) { + if (_mesa_rgba_logicop_enabled(ctx)) { i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | ENABLE_LOGIC_OP_MASK); i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | @@ -291,10 +292,10 @@ i830_set_blend_state(struct gl_context * ctx) funcRGB = - SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) - | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); + SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcRGB)) + | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstRGB)); - switch (ctx->Color.BlendEquationRGB) { + switch (ctx->Color.Blend[0].EquationRGB) { case GL_FUNC_ADD: eqnRGB = BLENDFUNC_ADD; break; @@ -314,15 +315,15 @@ i830_set_blend_state(struct gl_context * ctx) break; default: fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); + __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB); return; } - funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) - | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); + funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcA)) + | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstA)); - switch (ctx->Color.BlendEquationA) { + switch (ctx->Color.Blend[0].EquationA) { case GL_FUNC_ADD: eqnA = BLENDFUNC_ADD; break; @@ -342,7 +343,7 @@ i830_set_blend_state(struct gl_context * ctx) break; default: fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); + __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA); return; } @@ -679,7 +680,7 @@ update_specular(struct gl_context * ctx) I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - if (NEED_SECONDARY_COLOR(ctx)) + if (_mesa_need_secondary_color(ctx)) i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; else i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index b3bb8837cc..c35b4b5ed0 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -28,13 +28,14 @@ #include "main/mtypes.h" #include "main/enums.h" #include "main/colormac.h" +#include "main/macros.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" #include "i830_context.h" #include "i830_reg.h" - +#include "intel_chipset.h" static GLuint @@ -139,9 +140,9 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /* Get first image here, since intelObj->firstLevel will get set in * the intel_finalize_mipmap_tree() call above. */ - firstImage = tObj->Image[0][intelObj->firstLevel]; + firstImage = tObj->Image[0][tObj->BaseLevel]; - intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0, + intel_miptree_get_image_offset(intelObj->mt, tObj->BaseLevel, 0, 0, &dst_x, &dst_y); drm_intel_bo_reference(intelObj->mt->region->buffer); @@ -189,6 +190,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) { GLuint minFilt, mipFilt, magFilt; + float maxlod; + uint32_t minlod_fixed, maxlod_fixed; switch (tObj->MinFilter) { case GL_NEAREST: @@ -252,10 +255,24 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; #endif - state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - - intelObj->firstLevel) * - 4) << TM0S3_MIN_MIP_SHIFT; - + /* We get one field with fraction bits for the maximum + * addressable (smallest resolution) LOD. Use it to cover both + * MAX_LEVEL and MAX_LOD. + */ + minlod_fixed = U_FIXED(CLAMP(tObj->MinLod, 0.0, 11), 4); + maxlod = MIN2(tObj->MaxLod, tObj->_MaxLevel - tObj->BaseLevel); + if (intel->intelScreen->deviceID == PCI_CHIP_I855_GM || + intel->intelScreen->deviceID == PCI_CHIP_I865_G) { + maxlod_fixed = U_FIXED(CLAMP(maxlod, 0.0, 11.75), 2); + maxlod_fixed = MAX2(maxlod_fixed, (minlod_fixed + 3) >> 2); + state[I830_TEXREG_TM0S3] |= maxlod_fixed << TM0S3_MIN_MIP_SHIFT; + state[I830_TEXREG_TM0S2] |= TM0S2_LOD_PRECLAMP; + } else { + maxlod_fixed = U_FIXED(CLAMP(maxlod, 0.0, 11), 0); + maxlod_fixed = MAX2(maxlod_fixed, (minlod_fixed + 15) >> 4); + state[I830_TEXREG_TM0S3] |= maxlod_fixed << TM0S3_MIN_MIP_SHIFT_830; + } + state[I830_TEXREG_TM0S3] |= minlod_fixed << TM0S3_MAX_MIP_SHIFT; state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | (mipFilt << TM0S3_MIP_FILTER_SHIFT) | (magFilt << TM0S3_MAG_FILTER_SHIFT)); diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index f7fdb78d05..19f0807759 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -364,7 +364,7 @@ i830_emit_invarient_state(struct intel_context *intel) #define emit( intel, state, size ) \ - intel_batchbuffer_data(intel->batch, state, size ) + intel_batchbuffer_data(intel, state, size, false) static GLuint get_dirty(struct i830_hw_state *state) @@ -428,14 +428,15 @@ i830_emit_state(struct intel_context *intel) * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. */ - intel_batchbuffer_require_space(intel->batch, - get_state_size(state) + INTEL_PRIM_EMIT_SIZE); + intel_batchbuffer_require_space(intel, + get_state_size(state) + INTEL_PRIM_EMIT_SIZE, + false); count = 0; again: aper_count = 0; dirty = get_dirty(state); - aper_array[aper_count++] = intel->batch->buf; + aper_array[aper_count++] = intel->batch.bo; if (dirty & I830_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) @@ -452,7 +453,7 @@ i830_emit_state(struct intel_context *intel) if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) { if (count == 0) { count++; - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i830 emit state"); @@ -534,14 +535,9 @@ i830_emit_state(struct intel_context *intel) BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1); OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); - if (state->tex_buffer[i]) { - OUT_RELOC(state->tex_buffer[i], - I915_GEM_DOMAIN_SAMPLER, 0, - state->tex_offset[i]); - } - else { - OUT_BATCH(state->tex_offset[i]); - } + OUT_RELOC(state->tex_buffer[i], + I915_GEM_DOMAIN_SAMPLER, 0, + state->tex_offset[i]); OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); @@ -560,9 +556,7 @@ i830_emit_state(struct intel_context *intel) } } - intel->batch->dirty_state &= ~dirty; assert(get_dirty(state) == 0); - assert((intel->batch->dirty_state & (1<<1)) == 0); } static void @@ -584,6 +578,27 @@ i830_destroy_context(struct intel_context *intel) _tnl_free_vertices(&intel->ctx); } +static uint32_t i830_render_target_format_for_mesa_format[MESA_FORMAT_COUNT] = +{ + [MESA_FORMAT_ARGB8888] = DV_PF_8888, + [MESA_FORMAT_XRGB8888] = DV_PF_8888, + [MESA_FORMAT_RGB565] = DV_PF_565, + [MESA_FORMAT_ARGB1555] = DV_PF_1555, + [MESA_FORMAT_ARGB4444] = DV_PF_4444, +}; + +static bool +i830_render_target_supported(gl_format format) +{ + if (format == MESA_FORMAT_S8_Z24 || + format == MESA_FORMAT_X8_Z24 || + format == MESA_FORMAT_Z16) { + return true; + } + + return i830_render_target_format_for_mesa_format[format] != 0; +} + static void i830_set_draw_region(struct intel_context *intel, struct intel_region *color_regions[], @@ -623,24 +638,7 @@ i830_set_draw_region(struct intel_context *intel, DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */ if (irb != NULL) { - switch (irb->Base.Format) { - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_XRGB8888: - value |= DV_PF_8888; - break; - case MESA_FORMAT_RGB565: - value |= DV_PF_565; - break; - case MESA_FORMAT_ARGB1555: - value |= DV_PF_1555; - break; - case MESA_FORMAT_ARGB4444: - value |= DV_PF_4444; - break; - default: - _mesa_problem(ctx, "Bad renderbuffer format: %d\n", - irb->Base.Format); - } + value |= i830_render_target_format_for_mesa_format[irb->Base.Format]; } if (depth_region && depth_region->cpp == 4) { @@ -728,4 +726,5 @@ i830InitVtbl(struct i830_context *i830) i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; i830->intel.vtbl.finish_batch = intel_finish_vb; i830->intel.vtbl.invalidate_state = i830_invalidate_state; + i830->intel.vtbl.render_target_supported = i830_render_target_supported; } diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index f32f3cf602..7389a1d57a 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -168,15 +168,37 @@ i915CreateContext(int api, MIN2(ctx->Const.FragmentProgram.MaxNativeParameters, ctx->Const.FragmentProgram.MaxEnvParams); + /* i915 stores all values in single-precision floats. Values aren't set + * for other program targets because software is used for those targets. + */ + ctx->Const.FragmentProgram.MediumFloat.RangeMin = 127; + ctx->Const.FragmentProgram.MediumFloat.RangeMax = 127; + ctx->Const.FragmentProgram.MediumFloat.Precision = 23; + ctx->Const.FragmentProgram.LowFloat = ctx->Const.FragmentProgram.HighFloat = + ctx->Const.FragmentProgram.MediumFloat; + ctx->Const.FragmentProgram.MediumInt.RangeMin = 24; + ctx->Const.FragmentProgram.MediumInt.RangeMax = 24; + ctx->Const.FragmentProgram.MediumInt.Precision = 0; + ctx->Const.FragmentProgram.LowInt = ctx->Const.FragmentProgram.HighInt = + ctx->Const.FragmentProgram.MediumInt; + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; /* FINISHME: Are there other options that should be enabled for software * FINISHME: vertex shaders? */ ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitCondCodes = GL_TRUE; - ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoIfs = GL_TRUE; - ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoNoise = GL_TRUE; - ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT].EmitNoPow = GL_TRUE; + + struct gl_shader_compiler_options *const fs_options = + & ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; + fs_options->EmitNoIfs = GL_TRUE; + fs_options->EmitNoNoise = GL_TRUE; + fs_options->EmitNoPow = GL_TRUE; + fs_options->EmitNoMainReturn = GL_TRUE; + fs_options->EmitNoIndirectInput = GL_TRUE; + fs_options->EmitNoIndirectOutput = GL_TRUE; + fs_options->EmitNoIndirectUniform = GL_TRUE; + fs_options->EmitNoIndirectTemp = GL_TRUE; ctx->Const.MaxDrawBuffers = 1; diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 2c80ded075..601620275f 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -29,7 +29,6 @@ #define I915CONTEXT_INC #include "intel_context.h" -#include "i915_reg.h" #define I915_FALLBACK_TEXTURE 0x1000 #define I915_FALLBACK_COLORMASK 0x2000 @@ -51,6 +50,7 @@ #define I915_UPLOAD_INVARIENT 0x40 #define I915_UPLOAD_DEFAULTS 0x80 #define I915_UPLOAD_RASTER_RULES 0x100 +#define I915_UPLOAD_BLEND 0x200 #define I915_UPLOAD_TEX(i) (0x00010000<<(i)) #define I915_UPLOAD_TEX_ALL (0x00ff0000) #define I915_UPLOAD_TEX_0_SHIFT 16 @@ -77,17 +77,19 @@ #define I915_DEST_SETUP_SIZE 18 #define I915_CTXREG_STATE4 0 -#define I915_CTXREG_LI 1 -#define I915_CTXREG_LIS2 2 -#define I915_CTXREG_LIS4 3 -#define I915_CTXREG_LIS5 4 -#define I915_CTXREG_LIS6 5 -#define I915_CTXREG_IAB 6 -#define I915_CTXREG_BLENDCOLOR0 7 -#define I915_CTXREG_BLENDCOLOR1 8 -#define I915_CTXREG_BF_STENCIL_OPS 9 -#define I915_CTXREG_BF_STENCIL_MASKS 10 -#define I915_CTX_SETUP_SIZE 11 +#define I915_CTXREG_LI 1 +#define I915_CTXREG_LIS2 2 +#define I915_CTXREG_LIS4 3 +#define I915_CTXREG_LIS5 4 +#define I915_CTXREG_LIS6 5 +#define I915_CTXREG_BF_STENCIL_OPS 6 +#define I915_CTXREG_BF_STENCIL_MASKS 7 +#define I915_CTX_SETUP_SIZE 8 + +#define I915_BLENDREG_IAB 0 +#define I915_BLENDREG_BLENDCOLOR0 1 +#define I915_BLENDREG_BLENDCOLOR1 2 +#define I915_BLEND_SETUP_SIZE 3 #define I915_FOGREG_COLOR 0 #define I915_FOGREG_MODE0 1 @@ -123,6 +125,12 @@ enum { #define I915_MAX_CONSTANT 32 #define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) +#define I915_MAX_TEX_INDIRECT 4 +#define I915_MAX_TEX_INSN 32 +#define I915_MAX_ALU_INSN 64 +#define I915_MAX_DECL_INSN 27 +#define I915_MAX_TEMPORARY 16 + #define I915_MAX_INSN (I915_MAX_DECL_INSN + \ I915_MAX_TEX_INSN + \ I915_MAX_ALU_INSN) @@ -216,6 +224,7 @@ struct i915_fragment_program struct i915_hw_state { GLuint Ctx[I915_CTX_SETUP_SIZE]; + GLuint Blend[I915_BLEND_SETUP_SIZE]; GLuint Buffer[I915_DEST_SETUP_SIZE]; GLuint Stipple[I915_STP_SETUP_SIZE]; GLuint Fog[I915_FOG_SETUP_SIZE]; @@ -260,8 +269,12 @@ struct i915_context struct i915_fragment_program *current_program; + drm_intel_bo *current_vb_bo; + unsigned int current_vertex_size; + struct i915_hw_state state; uint32_t last_draw_offset; + GLuint last_sampler; }; diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 7a9fb7f088..2bfe665cb6 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -269,7 +269,7 @@ translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) #define EMIT_TEX( OP ) \ do { \ GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ - const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current; \ + const struct gl_fragment_program *program = &p->FragProg; \ GLuint unit = program->Base.SamplerUnits[inst->TexSrcUnit]; \ GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ unit, dim); \ @@ -304,8 +304,9 @@ do { \ */ static void calc_live_regs( struct i915_fragment_program *p ) { - const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current; + const struct gl_fragment_program *program = &p->FragProg; GLuint regsUsed = 0xffff0000; + uint8_t live_components[16] = { 0, }; GLint i; for (i = program->Base.NumInstructions - 1; i >= 0; i--) { @@ -314,13 +315,26 @@ static void calc_live_regs( struct i915_fragment_program *p ) int a; /* Register is written to: unmark as live for this and preceeding ops */ - if (inst->DstReg.File == PROGRAM_TEMPORARY) - regsUsed &= ~(1 << inst->DstReg.Index); + if (inst->DstReg.File == PROGRAM_TEMPORARY) { + live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask; + if (live_components[inst->DstReg.Index] == 0) + regsUsed &= ~(1 << inst->DstReg.Index); + } for (a = 0; a < opArgs; a++) { /* Register is read from: mark as live for this and preceeding ops */ - if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) + if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) { + unsigned c; + regsUsed |= 1 << inst->SrcReg[a].Index; + + for (c = 0; c < 4; c++) { + const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c); + + if (field <= SWIZZLE_W) + live_components[inst->SrcReg[a].Index] |= (1U << field); + } + } } p->usedRegs[i] = regsUsed; @@ -330,7 +344,7 @@ static void calc_live_regs( struct i915_fragment_program *p ) static GLuint get_live_regs( struct i915_fragment_program *p, const struct prog_instruction *inst ) { - const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current; + const struct gl_fragment_program *program = &p->FragProg; GLuint nr = inst - program->Base.Instructions; return p->usedRegs[nr]; @@ -351,8 +365,7 @@ static GLuint get_live_regs( struct i915_fragment_program *p, static void upload_program(struct i915_fragment_program *p) { - const struct gl_fragment_program *program = - p->ctx->FragmentProgram._Current; + const struct gl_fragment_program *program = &p->FragProg; const struct prog_instruction *inst = program->Base.Instructions; if (INTEL_DEBUG & DEBUG_WM) @@ -795,18 +808,18 @@ upload_program(struct i915_fragment_program *p) flags = get_result_flags(inst); dst = get_result_vector(p, inst); - /* dst = src1 >= src2 */ + /* tmp = src1 >= src2 */ i915_emit_arith(p, A0_SGE, - dst, + tmp, flags, 0, src_vector(p, &inst->SrcReg[0], program), src_vector(p, &inst->SrcReg[1], program), 0); - /* tmp = src1 <= src2 */ + /* dst = src1 <= src2 */ i915_emit_arith(p, A0_SGE, - tmp, + dst, flags, 0, negate(src_vector(p, &inst->SrcReg[0], program), 1, 1, 1, 1), @@ -944,18 +957,18 @@ upload_program(struct i915_fragment_program *p) flags = get_result_flags(inst); dst = get_result_vector(p, inst); - /* dst = src1 < src2 */ + /* tmp = src1 < src2 */ i915_emit_arith(p, A0_SLT, - dst, + tmp, flags, 0, src_vector(p, &inst->SrcReg[0], program), src_vector(p, &inst->SrcReg[1], program), 0); - /* tmp = src1 > src2 */ + /* dst = src1 > src2 */ i915_emit_arith(p, A0_SLT, - tmp, + dst, flags, 0, negate(src_vector(p, &inst->SrcReg[0], program), 1, 1, 1, 1), @@ -1152,7 +1165,7 @@ translate_program(struct i915_fragment_program *p) if (INTEL_DEBUG & DEBUG_WM) { printf("fp:\n"); - _mesa_print_program(&p->ctx->FragmentProgram._Current->Base); + _mesa_print_program(&p->FragProg.Base); printf("\n"); } @@ -1162,11 +1175,6 @@ translate_program(struct i915_fragment_program *p) fixup_depth_write(p); i915_fini_program(p); - if (INTEL_DEBUG & DEBUG_WM) { - printf("i915:\n"); - i915_disassemble_program(i915->state.Program, i915->state.ProgramSize); - } - p->translated = 1; } @@ -1413,6 +1421,10 @@ i915ValidateFragmentProgram(struct i915_context *i915) intel->vertex_attr_count, intel->ViewportMatrix.m, 0); + assert(intel->prim.current_offset == intel->prim.start_offset); + intel->prim.start_offset = (intel->prim.current_offset + intel->vertex_size-1) / intel->vertex_size * intel->vertex_size; + intel->prim.current_offset = intel->prim.start_offset; + intel->vertex_size >>= 2; i915->state.Ctx[I915_CTXREG_LIS2] = s2; @@ -1427,6 +1439,11 @@ i915ValidateFragmentProgram(struct i915_context *i915) if (!p->on_hardware) i915_upload_program(i915, p); + + if (INTEL_DEBUG & DEBUG_WM) { + printf("i915:\n"); + i915_disassemble_program(i915->state.Program, i915->state.ProgramSize); + } } void diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index ca1949b223..507adf1d3d 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -538,6 +538,7 @@ i915_upload_program(struct i915_context *i915, { GLuint program_size = p->csr - p->program; GLuint decl_size = p->decl - p->declarations; + GLuint nr; if (p->error) return; @@ -554,32 +555,32 @@ i915_upload_program(struct i915_context *i915, i915->state.ProgramSize = decl_size + program_size; } - /* Always seemed to get a failure if I used memcmp() to - * shortcircuit this state upload. Needs further investigation? - */ - if (p->nr_constants) { - GLuint nr = p->nr_constants; - - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); - I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); - - i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); - i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); - - memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); - i915->state.ConstantSize = 2 + (nr) * 4; - - if (0) { - GLuint i; - for (i = 0; i < nr; i++) { - fprintf(stderr, "const[%d]: %f %f %f %f\n", i, - p->constant[i][0], - p->constant[i][1], p->constant[i][2], p->constant[i][3]); - } + nr = p->nr_constants; + if (i915->state.ConstantSize != 2 + nr*4 || + memcmp(i915->state.Constant + 2, + p->constant, 4*sizeof(int)*nr)) { + if (nr) { + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); + I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); + + i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4); + i915->state.Constant[1] = (1 << nr) -1; + + memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * nr); + i915->state.ConstantSize = 2 + nr * 4; + + if (0) { + GLuint i; + for (i = 0; i < nr; i++) { + fprintf(stderr, "const[%d]: %f %f %f %f\n", i, + p->constant[i][0], + p->constant[i][1], p->constant[i][2], p->constant[i][3]); + } + } + } + else { + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); } - } - else { - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); } p->on_hardware = 1; diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h index 7f31ff674f..766547a4c6 100644 --- a/src/mesa/drivers/dri/i915/i915_reg.h +++ b/src/mesa/drivers/dri/i915/i915_reg.h @@ -361,13 +361,6 @@ /* p222 */ -#define I915_MAX_TEX_INDIRECT 4 -#define I915_MAX_TEX_INSN 32 -#define I915_MAX_ALU_INSN 64 -#define I915_MAX_DECL_INSN 27 -#define I915_MAX_TEMPORARY 16 - - /* Each instruction is 3 dwords long, though most don't require all * this space. Maximum of 123 instructions. Smaller maxes per insn * type. diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 9508fbaf94..3b1af4c455 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -31,6 +31,7 @@ #include "main/macros.h" #include "main/enums.h" #include "main/dd.h" +#include "main/state.h" #include "tnl/tnl.h" #include "tnl/t_context.h" @@ -56,8 +57,7 @@ i915_update_stencil(struct gl_context * ctx) GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass; GLuint back_ref, back_writemask, back_mask; GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + GLuint dirty = 0; /* The 915 considers CW to be "front" for two-sided stencil, so choose * appropriately. @@ -94,56 +94,68 @@ i915_update_stencil(struct gl_context * ctx) back_pass_z_fail = ctx->Stencil.ZFailFunc[0]; back_pass_z_pass = ctx->Stencil.ZPassFunc[0]; } +#define set_ctx_bits(reg, mask, set) do{ \ + GLuint dw = i915->state.Ctx[reg]; \ + dw &= ~(mask); \ + dw |= (set); \ + dirty |= dw != i915->state.Ctx[reg]; \ + i915->state.Ctx[reg] = dw; \ +} while(0) /* Set front state. */ - i915->state.Ctx[I915_CTXREG_STATE4] &= ~(MODE4_ENABLE_STENCIL_TEST_MASK | - MODE4_ENABLE_STENCIL_WRITE_MASK); - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_TEST_MASK(front_mask) | - STENCIL_WRITE_MASK(front_writemask)); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK | - S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= - (front_ref << S5_STENCIL_REF_SHIFT) | - (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) | - (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) | - (intel_translate_stencil_op(front_pass_z_fail) << - S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (intel_translate_stencil_op(front_pass_z_pass) << - S5_STENCIL_PASS_Z_PASS_SHIFT); + set_ctx_bits(I915_CTXREG_STATE4, + MODE4_ENABLE_STENCIL_TEST_MASK | + MODE4_ENABLE_STENCIL_WRITE_MASK, + ENABLE_STENCIL_TEST_MASK | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_TEST_MASK(front_mask) | + STENCIL_WRITE_MASK(front_writemask)); + + set_ctx_bits(I915_CTXREG_LIS5, + S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK | + S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK, + (front_ref << S5_STENCIL_REF_SHIFT) | + (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) | + (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) | + (intel_translate_stencil_op(front_pass_z_fail) << + S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (intel_translate_stencil_op(front_pass_z_pass) << + S5_STENCIL_PASS_Z_PASS_SHIFT)); /* Set back state if different from front. */ if (ctx->Stencil._TestTwoSide) { - i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= - ~(BFO_STENCIL_REF_MASK | - BFO_STENCIL_TEST_MASK | - BFO_STENCIL_FAIL_MASK | - BFO_STENCIL_PASS_Z_FAIL_MASK | - BFO_STENCIL_PASS_Z_PASS_MASK); - i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] |= BFO_STENCIL_TWO_SIDE | - (back_ref << BFO_STENCIL_REF_SHIFT) | - (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) | - (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) | - (intel_translate_stencil_op(back_pass_z_fail) << - BFO_STENCIL_PASS_Z_FAIL_SHIFT) | - (intel_translate_stencil_op(back_pass_z_pass) << - BFO_STENCIL_PASS_Z_PASS_SHIFT); - - i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] &= - ~(BFM_STENCIL_TEST_MASK_MASK | - BFM_STENCIL_WRITE_MASK_MASK); - i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] |= - BFM_STENCIL_TEST_MASK(back_mask) | - BFM_STENCIL_WRITE_MASK(back_writemask); + set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, + BFO_STENCIL_REF_MASK | + BFO_STENCIL_TEST_MASK | + BFO_STENCIL_FAIL_MASK | + BFO_STENCIL_PASS_Z_FAIL_MASK | + BFO_STENCIL_PASS_Z_PASS_MASK, + BFO_STENCIL_TWO_SIDE | + (back_ref << BFO_STENCIL_REF_SHIFT) | + (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) | + (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) | + (intel_translate_stencil_op(back_pass_z_fail) << + BFO_STENCIL_PASS_Z_FAIL_SHIFT) | + (intel_translate_stencil_op(back_pass_z_pass) << + BFO_STENCIL_PASS_Z_PASS_SHIFT)); + + set_ctx_bits(I915_CTXREG_BF_STENCIL_MASKS, + BFM_STENCIL_TEST_MASK_MASK | + BFM_STENCIL_WRITE_MASK_MASK, + BFM_STENCIL_TEST_MASK(back_mask) | + BFM_STENCIL_WRITE_MASK(back_writemask)); } else { - i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= ~BFO_STENCIL_TWO_SIDE; + set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, + BFO_STENCIL_TWO_SIDE, 0); } + +#undef set_ctx_bits + + if (dirty) + I915_STATECHANGE(i915, I915_UPLOAD_CTX); } static void @@ -169,15 +181,18 @@ i915AlphaFunc(struct gl_context * ctx, GLenum func, GLfloat ref) struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; + GLuint dw; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | - S6_ALPHA_REF_MASK); - i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | - (((GLuint) refByte) << - S6_ALPHA_REF_SHIFT)); + dw = i915->state.Ctx[I915_CTXREG_LIS6]; + dw &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); + dw |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } } /* This function makes sure that the proper enables are @@ -190,23 +205,32 @@ static void i915EvalLogicOpBlendState(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint dw0, dw1; - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw0 = i915->state.Ctx[I915_CTXREG_LIS5]; + dw1 = i915->state.Ctx[I915_CTXREG_LIS6]; - if (RGBA_LOGICOP_ENABLED(ctx)) { - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + if (_mesa_rgba_logicop_enabled(ctx)) { + dw0 |= S5_LOGICOP_ENABLE; + dw1 &= ~S6_CBUF_BLEND_ENABLE; } else { - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; + dw0 &= ~S5_LOGICOP_ENABLE; if (ctx->Color.BlendEnabled) { - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; + dw1 |= S6_CBUF_BLEND_ENABLE; } else { - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + dw1 &= ~S6_CBUF_BLEND_ENABLE; } } + if (dw0 != i915->state.Ctx[I915_CTXREG_LIS5] || + dw1 != i915->state.Ctx[I915_CTXREG_LIS6]) { + i915->state.Ctx[I915_CTXREG_LIS5] = dw0; + i915->state.Ctx[I915_CTXREG_LIS6] = dw1; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } } static void @@ -214,6 +238,7 @@ i915BlendColor(struct gl_context * ctx, const GLfloat color[4]) { struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; + GLuint dw; DBG("%s\n", __FUNCTION__); @@ -222,9 +247,11 @@ i915BlendColor(struct gl_context * ctx, const GLfloat color[4]) UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = - (a << 24) | (r << 16) | (g << 8) | b; + dw = (a << 24) | (r << 16) | (g << 8) | b; + if (dw != i915->state.Blend[I915_BLENDREG_BLENDCOLOR1]) { + i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_BLEND); + } } @@ -258,7 +285,7 @@ static void i915UpdateBlendState(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & + GLuint iab = (i915->state.Blend[I915_BLENDREG_IAB] & ~(IAB_SRC_FACTOR_MASK | IAB_DST_FACTOR_MASK | (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); @@ -267,12 +294,12 @@ i915UpdateBlendState(struct gl_context * ctx) ~(S6_CBUF_SRC_BLEND_FACT_MASK | S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); - GLuint eqRGB = ctx->Color.BlendEquationRGB; - GLuint eqA = ctx->Color.BlendEquationA; - GLuint srcRGB = ctx->Color.BlendSrcRGB; - GLuint dstRGB = ctx->Color.BlendDstRGB; - GLuint srcA = ctx->Color.BlendSrcA; - GLuint dstA = ctx->Color.BlendDstA; + GLuint eqRGB = ctx->Color.Blend[0].EquationRGB; + GLuint eqA = ctx->Color.Blend[0].EquationA; + GLuint srcRGB = ctx->Color.Blend[0].SrcRGB; + GLuint dstRGB = ctx->Color.Blend[0].DstRGB; + GLuint srcA = ctx->Color.Blend[0].SrcA; + GLuint dstA = ctx->Color.Blend[0].DstA; if (eqRGB == GL_MIN || eqRGB == GL_MAX) { srcRGB = dstRGB = GL_ONE; @@ -293,11 +320,13 @@ i915UpdateBlendState(struct gl_context * ctx) if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) iab |= IAB_ENABLE; - if (iab != i915->state.Ctx[I915_CTXREG_IAB] || - lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_IAB] = iab; + if (iab != i915->state.Blend[I915_BLENDREG_IAB]) { + i915->state.Blend[I915_BLENDREG_IAB] = iab; + I915_STATECHANGE(i915, I915_UPLOAD_BLEND); + } + if (lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = lis6; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); } /* This will catch a logicop blend equation */ @@ -325,27 +354,36 @@ i915DepthFunc(struct gl_context * ctx, GLenum func) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); + GLuint dw; DBG("%s\n", __FUNCTION__); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; + dw = i915->state.Ctx[I915_CTXREG_LIS6]; + dw &= ~S6_DEPTH_TEST_FUNC_MASK; + dw |= test << S6_DEPTH_TEST_FUNC_SHIFT; + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + } } static void i915DepthMask(struct gl_context * ctx, GLboolean flag) { struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint dw; DBG("%s flag (%d)\n", __FUNCTION__, flag); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (flag && ctx->Depth.Test) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; + dw |= S6_DEPTH_WRITE_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; + dw &= ~S6_DEPTH_WRITE_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + } } @@ -532,7 +570,7 @@ static void i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused) { struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint mode; + GLuint mode, dw; DBG("%s %d\n", __FUNCTION__, ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); @@ -554,9 +592,13 @@ i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused) mode = S4_CULLMODE_BOTH; } - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; - i915->state.Ctx[I915_CTXREG_LIS4] |= mode; + dw = i915->state.Ctx[I915_CTXREG_LIS4]; + dw &= ~S4_CULLMODE_MASK; + dw |= mode; + if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { + i915->state.Ctx[I915_CTXREG_LIS4] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } } static void @@ -690,6 +732,7 @@ i915_update_fog(struct gl_context * ctx) GLenum mode; GLboolean enabled; GLboolean try_pixel_fog; + GLuint dw; if (ctx->FragmentProgram._Current) { /* Pull in static fog state from program */ @@ -765,12 +808,16 @@ i915_update_fog(struct gl_context * ctx) i915->vertex_fog = I915_FOG_VERTEX; } - I915_STATECHANGE(i915, I915_UPLOAD_CTX); I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); + dw = i915->state.Ctx[I915_CTXREG_LIS5]; if (enabled) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; + dw |= S5_FOG_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; + dw &= ~S5_FOG_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { + i915->state.Ctx[I915_CTXREG_LIS5] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } /* Always enable pixel fog. Vertex fog using fog coord will conflict * with fog code appended onto fragment program. @@ -837,6 +884,7 @@ static void i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) { struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint dw; switch (cap) { case GL_TEXTURE_2D: @@ -848,11 +896,15 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) break; case GL_ALPHA_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; + dw |= S6_ALPHA_TEST_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; + dw &= ~S6_ALPHA_TEST_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } break; case GL_BLEND: @@ -872,19 +924,27 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) break; case GL_DITHER: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS5]; if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + dw |= S5_COLOR_DITHER_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; + dw &= ~S5_COLOR_DITHER_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { + i915->state.Ctx[I915_CTXREG_LIS5] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } break; case GL_DEPTH_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; + dw |= S6_DEPTH_TEST_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + dw &= ~S6_DEPTH_TEST_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { + i915->state.Ctx[I915_CTXREG_LIS6] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } i915DepthMask(ctx, ctx->Depth.Mask); break; @@ -900,11 +960,15 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) break; case GL_LINE_SMOOTH: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS4]; if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; + dw |= S4_LINE_ANTIALIAS_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; + dw &= ~S4_LINE_ANTIALIAS_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { + i915->state.Ctx[I915_CTXREG_LIS4] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } break; case GL_FOG: @@ -923,13 +987,15 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) hw_stencil = (irbStencil && irbStencil->region); } if (hw_stencil) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); + dw = i915->state.Ctx[I915_CTXREG_LIS5]; if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); + dw |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); + dw &= ~(S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); + if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { + i915->state.Ctx[I915_CTXREG_LIS5] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } } else { FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); @@ -959,11 +1025,15 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) /* 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); + dw = i915->state.Ctx[I915_CTXREG_LIS4]; if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_SPRITE_POINT_ENABLE; + dw |= S4_SPRITE_POINT_ENABLE; else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_SPRITE_POINT_ENABLE; + dw &= ~S4_SPRITE_POINT_ENABLE; + if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { + i915->state.Ctx[I915_CTXREG_LIS4] = dw; + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + } break; case GL_POINT_SMOOTH: @@ -984,6 +1054,7 @@ i915_init_packets(struct i915_context *i915) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); + I915_STATECHANGE(i915, I915_UPLOAD_BLEND); /* Probably don't want to upload all this stuff every time one * piece changes. */ @@ -1010,13 +1081,13 @@ i915_init_packets(struct i915_context *i915) ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff)); - i915->state.Ctx[I915_CTXREG_IAB] = + i915->state.Blend[I915_BLENDREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = + i915->state.Blend[I915_BLENDREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; + i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = 0; i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] = _3DSTATE_BACKFACE_STENCIL_MASKS | @@ -1087,6 +1158,7 @@ i915_init_packets(struct i915_context *i915) i915->state.active = (I915_UPLOAD_PROGRAM | I915_UPLOAD_STIPPLE | I915_UPLOAD_CTX | + I915_UPLOAD_BLEND | I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT | I915_UPLOAD_RASTER_RULES); diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index bc05a5687c..442adbb63c 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -158,7 +158,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /* Get first image here, since intelObj->firstLevel will get set in * the intel_finalize_mipmap_tree() call above. */ - firstImage = tObj->Image[0][intelObj->firstLevel]; + firstImage = tObj->Image[0][tObj->BaseLevel]; drm_intel_bo_reference(intelObj->mt->region->buffer); i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 59dfe08563..921183b81d 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -217,7 +217,7 @@ i915_emit_invarient_state(struct intel_context *intel) #define emit(intel, state, size ) \ - intel_batchbuffer_data(intel->batch, state, size) + intel_batchbuffer_data(intel, state, size, false) static GLuint get_dirty(struct i915_hw_state *state) @@ -251,6 +251,9 @@ get_state_size(struct i915_hw_state *state) if (dirty & I915_UPLOAD_CTX) sz += sizeof(state->Ctx); + if (dirty & I915_UPLOAD_BLEND) + sz += sizeof(state->Blend); + if (dirty & I915_UPLOAD_BUFFERS) sz += sizeof(state->Buffer); @@ -299,14 +302,15 @@ i915_emit_state(struct intel_context *intel) * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. */ - intel_batchbuffer_require_space(intel->batch, - get_state_size(state) + INTEL_PRIM_EMIT_SIZE); + intel_batchbuffer_require_space(intel, + get_state_size(state) + INTEL_PRIM_EMIT_SIZE, + false); count = 0; again: aper_count = 0; dirty = get_dirty(state); - aper_array[aper_count++] = intel->batch->buf; + aper_array[aper_count++] = intel->batch.bo; if (dirty & I915_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) @@ -326,7 +330,7 @@ i915_emit_state(struct intel_context *intel) if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) { if (count == 0) { count++; - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state"); @@ -365,6 +369,13 @@ i915_emit_state(struct intel_context *intel) emit(intel, state->Ctx, sizeof(state->Ctx)); } + if (dirty & I915_UPLOAD_BLEND) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_BLEND:\n"); + + emit(intel, state->Blend, sizeof(state->Blend)); + } + if (dirty & I915_UPLOAD_BUFFERS) { GLuint count; @@ -425,6 +436,7 @@ i915_emit_state(struct intel_context *intel) */ if (dirty & I915_UPLOAD_TEX_ALL) { int nr = 0; + GLuint unwind; for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) @@ -435,21 +447,16 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { - - if (state->tex_buffer[i]) { - OUT_RELOC(state->tex_buffer[i], - I915_GEM_DOMAIN_SAMPLER, 0, - state->tex_offset[i]); - } - else { - OUT_BATCH(state->tex_offset[i]); - } + OUT_RELOC(state->tex_buffer[i], + I915_GEM_DOMAIN_SAMPLER, 0, + state->tex_offset[i]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); } ADVANCE_BATCH(); + unwind = intel->batch.used; BEGIN_BATCH(2 + nr * 3); OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); @@ -460,6 +467,13 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); } ADVANCE_BATCH(); + if (i915->last_sampler && + memcmp(intel->batch.map + i915->last_sampler, + intel->batch.map + unwind, + (2 + nr*3)*sizeof(int)) == 0) + intel->batch.used = unwind; + else + i915->last_sampler = unwind; } if (dirty & I915_UPLOAD_CONSTANTS) { @@ -481,9 +495,7 @@ i915_emit_state(struct intel_context *intel) } } - intel->batch->dirty_state &= ~dirty; assert(get_dirty(state) == 0); - assert((intel->batch->dirty_state & (1<<1)) == 0); } static void @@ -523,6 +535,27 @@ i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region, } } +static uint32_t i915_render_target_format_for_mesa_format[MESA_FORMAT_COUNT] = +{ + [MESA_FORMAT_ARGB8888] = DV_PF_8888, + [MESA_FORMAT_XRGB8888] = DV_PF_8888, + [MESA_FORMAT_RGB565] = DV_PF_565 | DITHER_FULL_ALWAYS, + [MESA_FORMAT_ARGB1555] = DV_PF_1555 | DITHER_FULL_ALWAYS, + [MESA_FORMAT_ARGB4444] = DV_PF_4444 | DITHER_FULL_ALWAYS, +}; + +static bool +i915_render_target_supported(gl_format format) +{ + if (format == MESA_FORMAT_S8_Z24 || + format == MESA_FORMAT_X8_Z24 || + format == MESA_FORMAT_Z16) { + return true; + } + + return i915_render_target_format_for_mesa_format[format] != 0; +} + static void i915_set_draw_region(struct intel_context *intel, struct intel_region *color_regions[], @@ -562,24 +595,7 @@ i915_set_draw_region(struct intel_context *intel, DSTORG_VERT_BIAS(0x8) | /* .5 */ LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); if (irb != NULL) { - switch (irb->Base.Format) { - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_XRGB8888: - value |= DV_PF_8888; - break; - case MESA_FORMAT_RGB565: - value |= DV_PF_565 | DITHER_FULL_ALWAYS; - break; - case MESA_FORMAT_ARGB1555: - value |= DV_PF_1555 | DITHER_FULL_ALWAYS; - break; - case MESA_FORMAT_ARGB4444: - value |= DV_PF_4444 | DITHER_FULL_ALWAYS; - break; - default: - _mesa_problem(ctx, "Bad renderbuffer format: %d\n", - irb->Base.Format); - } + value |= i915_render_target_format_for_mesa_format[irb->Base.Format]; } /* This isn't quite safe, thus being hidden behind an option. When changing @@ -661,6 +677,10 @@ i915_new_batch(struct intel_context *intel) */ i915->state.emitted = 0; i915->last_draw_offset = 0; + i915->last_sampler = 0; + + i915->current_vb_bo = NULL; + i915->current_vertex_size = 0; } static void @@ -686,4 +706,5 @@ i915InitVtbl(struct i915_context *i915) i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; i915->intel.vtbl.finish_batch = intel_finish_vb; + i915->intel.vtbl.render_target_supported = i915_render_target_supported; } diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 0d8ab4b507..2d361ca0a9 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -124,7 +124,7 @@ static INLINE GLuint intel_get_vb_max(struct intel_context *intel) GLuint ret; if (intel->intelScreen->no_vbo) - ret = intel->batch->size - 1500; + ret = sizeof(intel->batch.map) - 1500; else ret = INTEL_VB_SIZE; ret /= (intel->vertex_size * 4); diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index b9a8aeb12f..7bcb72f42d 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -54,6 +54,7 @@ #include "intel_span.h" #include "i830_context.h" #include "i830_reg.h" +#include "i915_context.h" static void intelRenderPrimitive(struct gl_context * ctx, GLenum prim); static void intelRasterPrimitive(struct gl_context * ctx, GLenum rprim, @@ -62,22 +63,22 @@ static void intelRasterPrimitive(struct gl_context * ctx, GLenum rprim, static void intel_flush_inline_primitive(struct intel_context *intel) { - GLuint used = intel->batch->ptr - intel->prim.start_ptr; + GLuint used = intel->batch.used - intel->prim.start_ptr; assert(intel->prim.primitive != ~0); /* printf("/\n"); */ - if (used < 8) + if (used < 2) goto do_discard; - *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | - intel->prim.primitive | (used / 4 - 2)); + intel->batch.map[intel->prim.start_ptr] = + _3DPRIMITIVE | intel->prim.primitive | (used - 2); goto finished; do_discard: - intel->batch->ptr -= used; + intel->batch.used = intel->prim.start_ptr; finished: intel->prim.primitive = ~0; @@ -100,9 +101,7 @@ static void intel_start_inline(struct intel_context *intel, uint32_t prim) */ BEGIN_BATCH(1); - assert((intel->batch->dirty_state & (1<<1)) == 0); - - intel->prim.start_ptr = intel->batch->ptr; + intel->prim.start_ptr = intel->batch.used; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; @@ -118,26 +117,25 @@ static void intel_wrap_inline(struct intel_context *intel) GLuint prim = intel->prim.primitive; intel_flush_inline_primitive(intel); - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); intel_start_inline(intel, prim); /* ??? */ } static GLuint *intel_extend_inline(struct intel_context *intel, GLuint dwords) { - GLuint sz = dwords * sizeof(GLuint); GLuint *ptr; assert(intel->prim.flush == intel_flush_inline_primitive); - if (intel_batchbuffer_space(intel->batch) < sz) + if (intel_batchbuffer_space(intel) < dwords * sizeof(GLuint)) intel_wrap_inline(intel); /* printf("."); */ intel->vtbl.assert_not_dirty(intel); - ptr = (GLuint *) intel->batch->ptr; - intel->batch->ptr += sz; + ptr = intel->batch.map + intel->batch.used; + intel->batch.used += dwords; return ptr; } @@ -218,15 +216,15 @@ void intel_flush_prim(struct intel_context *intel) offset = intel->prim.start_offset; intel->prim.start_offset = intel->prim.current_offset; if (intel->gen < 3) - intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128); + intel->prim.current_offset = intel->prim.start_offset = ALIGN(intel->prim.start_offset, 128); intel->prim.flush = NULL; intel->vtbl.emit_state(intel); - aper_array[0] = intel->batch->buf; + aper_array[0] = intel->batch.bo; aper_array[1] = vb_bo; if (dri_bufmgr_check_aperture_space(aper_array, 2)) { - intel_batchbuffer_flush(intel->batch); + intel_batchbuffer_flush(intel); intel->vtbl.emit_state(intel); } @@ -236,11 +234,6 @@ void intel_flush_prim(struct intel_context *intel) */ intel->no_batch_wrap = GL_TRUE; - /* Check that we actually emitted the state into this batch, using the - * UPLOAD_CTX bit as the signal. - */ - assert((intel->batch->dirty_state & (1<<1)) == 0); - #if 0 printf("emitting %d..%d=%d vertices size %d\n", offset, intel->prim.current_offset, count, @@ -248,20 +241,39 @@ void intel_flush_prim(struct intel_context *intel) #endif if (intel->gen >= 3) { - BEGIN_BATCH(5); - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(0) | I1_LOAD_S(1) | 1); - assert((offset & ~S0_VB_OFFSET_MASK) == 0); - OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset); - OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) | - (intel->vertex_size << S1_VERTEX_PITCH_SHIFT)); + struct i915_context *i915 = i915_context(&intel->ctx); + unsigned int cmd = 0, len = 0; + + if (vb_bo != i915->current_vb_bo) { + cmd |= I1_LOAD_S(0); + len++; + } + if (intel->vertex_size != i915->current_vertex_size) { + cmd |= I1_LOAD_S(1); + len++; + } + if (len) + len++; + + BEGIN_BATCH(2+len); + if (cmd) + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | cmd | (len - 2)); + if (vb_bo != i915->current_vb_bo) { + OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); + i915->current_vb_bo = vb_bo; + } + if (intel->vertex_size != i915->current_vertex_size) { + OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) | + (intel->vertex_size << S1_VERTEX_PITCH_SHIFT)); + i915->current_vertex_size = intel->vertex_size; + } OUT_BATCH(_3DPRIMITIVE | PRIM_INDIRECT | PRIM_INDIRECT_SEQUENTIAL | intel->prim.primitive | count); - OUT_BATCH(0); /* Beginning vertex index */ + OUT_BATCH(offset / (intel->vertex_size * 4)); ADVANCE_BATCH(); } else { struct i830_context *i830 = i830_context(&intel->ctx); @@ -478,6 +490,7 @@ static void intel_wpos_triangle(struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) { + const struct gl_framebuffer *fb = intel->ctx.DrawBuffer; GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); @@ -488,10 +501,11 @@ intel_wpos_triangle(struct intel_context *intel, __memcpy(v1_wpos, v1, size); __memcpy(v2_wpos, v2, size); - v0_wpos[1] = -v0_wpos[1] + intel->ctx.DrawBuffer->Height; - v1_wpos[1] = -v1_wpos[1] + intel->ctx.DrawBuffer->Height; - v2_wpos[1] = -v2_wpos[1] + intel->ctx.DrawBuffer->Height; - + if (!fb->Name) { + v0_wpos[1] = -v0_wpos[1] + fb->Height; + v1_wpos[1] = -v1_wpos[1] + fb->Height; + v2_wpos[1] = -v2_wpos[1] + fb->Height; + } intel_draw_triangle(intel, v0, v1, v2); } @@ -501,6 +515,7 @@ static void intel_wpos_line(struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1) { + const struct gl_framebuffer *fb = intel->ctx.DrawBuffer; GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); @@ -509,8 +524,10 @@ intel_wpos_line(struct intel_context *intel, __memcpy(v0_wpos, v0, size); __memcpy(v1_wpos, v1, size); - v0_wpos[1] = -v0_wpos[1] + intel->ctx.DrawBuffer->Height; - v1_wpos[1] = -v1_wpos[1] + intel->ctx.DrawBuffer->Height; + if (!fb->Name) { + v0_wpos[1] = -v0_wpos[1] + fb->Height; + v1_wpos[1] = -v1_wpos[1] + fb->Height; + } intel_draw_line(intel, v0, v1); } @@ -519,12 +536,15 @@ intel_wpos_line(struct intel_context *intel, static void intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) { + const struct gl_framebuffer *fb = intel->ctx.DrawBuffer; GLuint offset = intel->wpos_offset; GLuint size = intel->wpos_size; GLfloat *v0_wpos = (GLfloat *)((char *)v0 + offset); __memcpy(v0_wpos, v0, size); - v0_wpos[1] = -v0_wpos[1] + intel->ctx.DrawBuffer->Height; + + if (!fb->Name) + v0_wpos[1] = -v0_wpos[1] + fb->Height; intel_draw_point(intel, v0); } |