From 41b58954e1742493452b91d9ecdb761db5de3bed Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 10 Jun 2004 12:48:07 +0000 Subject: New driver for i915 as well as older i830/i845/i865 chipsets. --- src/mesa/drivers/dri/i915/i915_vtbl.c | 332 ++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 src/mesa/drivers/dri/i915/i915_vtbl.c (limited to 'src/mesa/drivers/dri/i915/i915_vtbl.c') diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c new file mode 100644 index 0000000000..cfea3545e7 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -0,0 +1,332 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" + +static void i915_render_start( intelContextPtr intel ) +{ + GLcontext *ctx = &intel->ctx; + i915ContextPtr i915 = I915_CONTEXT(intel); + + if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) + i915ValidateFragmentProgram( i915 ); + else + i915ValidateTextureProgram( i915 ); +} + + +static void i915_reduced_primitive_state( intelContextPtr intel, + GLenum rprim ) +{ + i915ContextPtr i915 = I915_CONTEXT(intel); + GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && + intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i915->intel.reduced_primitive = rprim; + + if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] = st1; + } +} + + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean i915_check_vertex_size( intelContextPtr intel, + GLuint expected ) +{ + i915ContextPtr i915 = I915_CONTEXT(intel); + int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int i, sz = 0; + + switch (lis4 & S4_VFMT_XYZW_MASK) { + case S4_VFMT_XY: sz = 2; break; + case S4_VFMT_XYZ: sz = 3; break; + case S4_VFMT_XYW: sz = 3; break; + case S4_VFMT_XYZW: sz = 4; break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (lis4 & S4_VFMT_SPEC_FOG) sz++; + if (lis4 & S4_VFMT_COLOR) sz++; + if (lis4 & S4_VFMT_DEPTH_OFFSET) sz++; + if (lis4 & S4_VFMT_POINT_WIDTH) sz++; + + for (i = 0 ; i < 8 ; i++) { + switch (lis2 & S2_TEXCOORD_FMT0_MASK) { + case TEXCOORDFMT_2D: sz += 2; break; + case TEXCOORDFMT_3D: sz += 3; break; + case TEXCOORDFMT_4D: sz += 4; break; + case TEXCOORDFMT_1D: sz += 1; break; + case TEXCOORDFMT_2D_16: sz += 1; break; + case TEXCOORDFMT_4D_16: sz += 2; break; + case TEXCOORDFMT_NOT_PRESENT: break; + default: + fprintf(stderr, "bad texcoord fmt %d\n", i); + return GL_FALSE; + } + lis2 >>= S2_TEXCOORD_FMT1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + + +static void i915_emit_invarient_state( intelContextPtr intel ) +{ + BATCH_LOCALS; + + BEGIN_BATCH( 200 ); + + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + /* Don't support texture crossbar yet */ + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | + CSB_TCB(5, 5) | + CSB_TCB(6, 6) | + CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_TEXKILL_3D_4D | + TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(3) | + (1)); + OUT_BATCH(0); + + /* XXX: Use this */ + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ + OUT_BATCH(0); + + + /* Don't support twosided stencil yet */ + OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_TWO_SIDE | + 0 ); + + ADVANCE_BATCH(); +} + + +#define emit( intel, state, size ) \ +do { \ + int k; \ + BEGIN_BATCH( (size) / sizeof(GLuint)); \ + for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \ + OUT_BATCH((state)[k]); \ + ADVANCE_BATCH(); \ +} while (0); + + +/* Push the state into the sarea and/or texture memory. + */ +static void i915_emit_state( intelContextPtr intel ) +{ + i915ContextPtr i915 = I915_CONTEXT(intel); + struct i915_hw_state *state = i915->current; + BATCH_LOCALS; + int i; + GLuint dirty; + + /* More to workaround the multitex hang - if one texture unit state + * is modified, emit all texture units. + */ + dirty = state->active & ~state->emitted; + if (dirty & I915_UPLOAD_TEX_ALL) + state->emitted &= ~I915_UPLOAD_TEX_ALL; + dirty = state->active & ~state->emitted; + + + if (VERBOSE) + fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); + + if (dirty & I915_UPLOAD_CTX) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); + emit( i915, state->Ctx, sizeof(state->Ctx) ); + } + + if (dirty & I915_UPLOAD_BUFFERS) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); + emit( i915, state->Buffer, sizeof(state->Buffer) ); + } + + if (dirty & I915_UPLOAD_STIPPLE) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); + emit( i915, state->Stipple, sizeof(state->Stipple) ); + } + + if (dirty & I915_UPLOAD_FOG) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); + emit( i915, state->Fog, sizeof(state->Fog) ); + } + + /* Combine all the dirty texture state into a single command to + * avoid lockups on I915 hardware. + */ + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + BEGIN_BATCH(2+nr*3); + OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr)); + 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)) { + OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]); + OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); + } + ADVANCE_BATCH(); + + BEGIN_BATCH(2+nr*3); + OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr)); + 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)) { + OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); + } + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_CONSTANTS) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); + emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) ); + } + + if (dirty & I915_UPLOAD_PROGRAM) { + if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); + + assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize); + + emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) ); + if (VERBOSE) + i915_disassemble_program( state->Program, state->ProgramSize ); + } + + state->emitted |= dirty; +} + +static void i915_destroy_context( intelContextPtr intel ) +{ + _tnl_free_vertices(&intel->ctx); +} + +static void i915_set_draw_offset( intelContextPtr intel, int offset ) +{ + i915ContextPtr i915 = I915_CONTEXT(intel); + I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS ); + i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset; +} + +static void i915_lost_hardware( intelContextPtr intel ) +{ + I915_CONTEXT(intel)->state.emitted = 0; +} + +static void i915_emit_flush( intelContextPtr intel ) +{ + BATCH_LOCALS; + + BEGIN_BATCH(2); + OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE ); + OUT_BATCH( 0 ); + ADVANCE_BATCH(); +} + + +void i915InitVtbl( i915ContextPtr i915 ) +{ + i915->intel.vtbl.alloc_tex_obj = i915AllocTexObj; + i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; + i915->intel.vtbl.clear_with_tris = i915ClearWithTris; + i915->intel.vtbl.destroy = i915_destroy_context; + i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state; + i915->intel.vtbl.emit_state = i915_emit_state; + i915->intel.vtbl.lost_hardware = i915_lost_hardware; + i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; + i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.set_draw_offset = i915_set_draw_offset; + i915->intel.vtbl.update_texture_state = i915UpdateTextureState; + i915->intel.vtbl.emit_flush = i915_emit_flush; +} + -- cgit v1.2.3