From cd32164cc68dac6d6e480d417aff02f091a2b49a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 1 Mar 2006 00:06:14 +0000 Subject: [PATCH] Port the i830 driver to the texture manager. Compiles but not tested. Turn back on some fallback cases. Turn back on the unclipped rastersetup-to-dma render path. --- src/mesa/drivers/dri/i915/Makefile | 17 +- src/mesa/drivers/dri/i915/i830_context.c | 37 +- src/mesa/drivers/dri/i915/i830_context.h | 90 ++- src/mesa/drivers/dri/i915/i830_metaops.c | 237 +++++-- src/mesa/drivers/dri/i915/i830_state.c | 44 +- src/mesa/drivers/dri/i915/i830_tex.c | 256 +------- src/mesa/drivers/dri/i915/i830_texblend.c | 8 +- src/mesa/drivers/dri/i915/i830_texstate.c | 587 +++++++----------- src/mesa/drivers/dri/i915/i830_vtbl.c | 110 +++- src/mesa/drivers/dri/i915/i915_context.h | 11 + src/mesa/drivers/dri/i915/i915_reg.h | 4 + src/mesa/drivers/dri/i915/i915_state.c | 13 + src/mesa/drivers/dri/i915/i915_vtbl.c | 3 +- src/mesa/drivers/dri/i915/intel_batchbuffer.c | 6 +- src/mesa/drivers/dri/i915/intel_batchbuffer.h | 2 +- src/mesa/drivers/dri/i915/intel_blit.c | 12 +- src/mesa/drivers/dri/i915/intel_buffers.c | 100 +-- src/mesa/drivers/dri/i915/intel_context.h | 5 - src/mesa/drivers/dri/i915/intel_pixel.c | 1 + src/mesa/drivers/dri/i915/intel_pixel_copy.c | 46 +- src/mesa/drivers/dri/i915/intel_pixel_draw.c | 18 +- src/mesa/drivers/dri/i915/intel_pixel_read.c | 93 +-- src/mesa/drivers/dri/i915/intel_render.c | 18 +- src/mesa/drivers/dri/i915/intel_tex_copy.c | 75 +-- src/mesa/drivers/dri/i915/intel_tris.c | 26 +- 25 files changed, 810 insertions(+), 1009 deletions(-) diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index e68fc3c634e..d1c0c1c260d 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -5,7 +5,15 @@ include $(TOP)/configs/current LIBNAME = i915_dri.so DRIVER_SOURCES = \ + i830_context.c \ + i830_metaops.c \ + i830_state.c \ + i830_texblend.c \ + i830_tex.c \ + i830_texstate.c \ + i830_vtbl.c \ bufmgr_fake.c \ + intel_render.c \ intel_regions.c \ intel_buffer_objects.c \ intel_batchbuffer.c \ @@ -41,15 +49,6 @@ DRIVER_SOURCES = \ intel_tris.c -DISABLED = \ - intel_render.c \ - i830_context.c \ - i830_metaops.c \ - i830_state.c \ - i830_texblend.c \ - i830_tex.c \ - i830_texstate.c \ - i830_vtbl.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 56d03864ad4..b66ca310592 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -58,7 +58,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, void *sharedContextPrivate) { struct dd_function_table functions; - i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context); + struct i830_context *i830 = CALLOC_STRUCT(i830_context); struct intel_context *intel = &i830->intel; GLcontext *ctx = &intel->ctx; if (!i830) return GL_FALSE; @@ -76,33 +76,14 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; - intel->nr_heaps = 1; - intel->texture_heaps[0] = - driCreateTextureHeap( 0, intel, - intel->intelScreen->tex.size, - 12, - I830_NR_TEX_REGIONS, - intel->sarea->texList, - & intel->sarea->texAge, - & intel->swapped, - sizeof( struct i830_texture_object ), - (destroy_texture_object_t *)intelDestroyTexObj ); - - /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly - * FIXME: packed, but they're not in Intel graphics hardware. + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: */ - intel->ctx.Const.MaxTextureUnits = 1; - driCalculateMaxTextureLevels( intel->texture_heaps, - intel->nr_heaps, - &intel->ctx.Const, - 4, - 11, /* max 2D texture size is 2048x2048 */ - 8, /* max 3D texture size is 256^3 */ - 10, /* max CUBE texture size is 1024x1024 */ - 11, /* max RECT. supported */ - 12, - GL_FALSE ); - intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 11; + ctx->Const.MaxTextureRectSize = (1<<11); + ctx->Const.MaxTextureUnits = I830_TEX_UNITS; _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, 18 * sizeof(GLfloat) ); @@ -112,7 +93,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, driInitExtensions( ctx, i830_extensions, GL_FALSE ); i830InitState( i830 ); - + i830InitMetaFuncs( i830 ); _tnl_allow_vertex_fog( ctx, 1 ); _tnl_allow_pixel_fog( ctx, 0 ); diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h index 6ab6ccb68ae..d7088d4fa86 100644 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -39,6 +39,7 @@ #define I830_UPLOAD_CTX 0x1 #define I830_UPLOAD_BUFFERS 0x2 #define I830_UPLOAD_STIPPLE 0x4 +#define I830_UPLOAD_INVARIENT 0x8 #define I830_UPLOAD_TEX(i) (0x10<<(i)) #define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) #define I830_UPLOAD_TEX_ALL (0x0f0) @@ -48,15 +49,15 @@ */ #define I830_DESTREG_CBUFADDR0 0 #define I830_DESTREG_CBUFADDR1 1 -#define I830_DESTREG_DBUFADDR0 3 -#define I830_DESTREG_DBUFADDR1 4 -#define I830_DESTREG_DV0 6 -#define I830_DESTREG_DV1 7 -#define I830_DESTREG_SENABLE 8 -#define I830_DESTREG_SR0 9 -#define I830_DESTREG_SR1 10 -#define I830_DESTREG_SR2 11 -#define I830_DEST_SETUP_SIZE 12 +#define I830_DESTREG_DBUFADDR0 2 +#define I830_DESTREG_DBUFADDR1 3 +#define I830_DESTREG_DV0 4 +#define I830_DESTREG_DV1 5 +#define I830_DESTREG_SENABLE 6 +#define I830_DESTREG_SR0 7 +#define I830_DESTREG_SR1 8 +#define I830_DESTREG_SR2 9 +#define I830_DEST_SETUP_SIZE 10 #define I830_CTXREG_STATE1 0 #define I830_CTXREG_STATE2 1 @@ -82,14 +83,13 @@ #define I830_STP_SETUP_SIZE 2 #define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ -#define I830_TEXREG_TM0S0 1 -#define I830_TEXREG_TM0S1 2 -#define I830_TEXREG_TM0S2 3 -#define I830_TEXREG_TM0S3 4 -#define I830_TEXREG_TM0S4 5 -#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */ -#define I830_TEXREG_CUBE 7 /* _3DSTATE_MAP_SUBE */ -#define I830_TEX_SETUP_SIZE 8 +#define I830_TEXREG_TM0S1 1 +#define I830_TEXREG_TM0S2 2 +#define I830_TEXREG_TM0S3 3 +#define I830_TEXREG_TM0S4 4 +#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ +#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ +#define I830_TEX_SETUP_SIZE 7 #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ @@ -108,6 +108,17 @@ struct i830_hw_state { GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; GLuint TexBlendWordsUsed[I830_TEX_UNITS]; + + struct intel_region *draw_region; + struct intel_region *depth_region; + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + GLuint tex_buffer[I830_TEX_UNITS]; + GLuint tex_offset[I830_TEX_UNITS]; + GLuint emitted; /* I810_UPLOAD_* */ GLuint active; }; @@ -116,15 +127,12 @@ struct i830_context { struct intel_context intel; + GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; GLuint last_index; struct i830_hw_state meta, initial, state, *current; }; -typedef struct i830_context *i830ContextPtr; -typedef struct i830_texture_object *i830TextureObjectPtr; - -#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx)) @@ -146,7 +154,7 @@ do { \ /* i830_vtbl.c */ extern void -i830InitVtbl( i830ContextPtr i830 ); +i830InitVtbl( struct i830_context *i830 ); /* i830_context.c */ @@ -163,17 +171,14 @@ i830UpdateTextureState( struct intel_context *intel ); extern void i830InitTextureFuncs( struct dd_function_table *functions ); -extern intelTextureObjectPtr -i830AllocTexObj( struct gl_texture_object *tObj ); - /* i830_texblend.c */ -extern GLuint i830SetTexEnvCombine(i830ContextPtr i830, +extern GLuint i830SetTexEnvCombine(struct i830_context *i830, const struct gl_tex_env_combine_state * combine, GLint blendUnit, GLuint texel_op, GLuint *state, const GLfloat *factor ); extern void -i830EmitTextureBlend( i830ContextPtr i830 ); +i830EmitTextureBlend( struct i830_context *i830 ); /* i830_state.c @@ -182,32 +187,25 @@ extern void i830InitStateFuncs( struct dd_function_table *functions ); extern void -i830EmitState( i830ContextPtr i830 ); +i830EmitState( struct i830_context *i830 ); extern void -i830InitState( i830ContextPtr i830 ); +i830InitState( struct i830_context *i830 ); /* i830_metaops.c */ -extern GLboolean -i830TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ); - -extern GLboolean -i830TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - extern void -i830ClearWithTris( struct intel_context *intel, GLbitfield mask, - GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); +i830InitMetaFuncs( struct i830_context *i830 ); +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct i830_context * +i830_context( GLcontext *ctx ) +{ + return (struct i830_context *)ctx; +} - #endif diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c index 635a73041a4..bf3813be4a8 100644 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -34,13 +34,15 @@ #include "intel_screen.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "intel_regions.h" #include "i830_context.h" #include "i830_reg.h" /* A large amount of state doesn't need to be uploaded. */ -#define ACTIVE (I830_UPLOAD_TEXBLEND(0) | \ +#define ACTIVE (I830_UPLOAD_INVARIENT | \ + I830_UPLOAD_TEXBLEND(0) | \ I830_UPLOAD_STIPPLE | \ I830_UPLOAD_CTX | \ I830_UPLOAD_BUFFERS | \ @@ -54,20 +56,11 @@ do { \ i830->current->emitted &= ~ACTIVE; \ } while (0) -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void set_initial_state( struct intel_context *intel ) -{ - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; -} - static void set_no_depth_stencil_write( struct intel_context *intel ) { + struct i830_context *i830 = i830_context(&intel->ctx); + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; @@ -92,6 +85,8 @@ static void set_stencil_replace( struct intel_context *intel, GLuint s_mask, GLuint s_clear) { + struct i830_context *i830 = i830_context(&intel->ctx); + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) */ i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; @@ -142,6 +137,8 @@ static void set_stencil_replace( struct intel_context *intel, static void set_color_mask( struct intel_context *intel, GLboolean state ) { + struct i830_context *i830 = i830_context(&intel->ctx); + const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | (1 << WRITEMASK_GREEN_SHIFT) | (1 << WRITEMASK_BLUE_SHIFT) | @@ -163,6 +160,7 @@ static void set_color_mask( struct intel_context *intel, GLboolean state ) */ static void set_no_texture( struct intel_context *intel ) { + struct i830_context *i830 = i830_context(&intel->ctx); static const struct gl_tex_env_combine_state comb = { GL_NONE, GL_NONE, { GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, @@ -181,9 +179,9 @@ static void set_no_texture( struct intel_context *intel ) /* Set up a single element blend stage for 'replace' texturing with no * funny ops. */ -static void enable_texture_blend_replace( struct intel_context *intel, - GLenum format ) +static void set_texture_blend_replace( struct intel_context *intel ) { + struct i830_context *i830 = i830_context(&intel->ctx); static const struct gl_tex_env_combine_state comb = { GL_REPLACE, GL_REPLACE, { GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, @@ -207,28 +205,80 @@ static void enable_texture_blend_replace( struct intel_context *intel, /* Set up an arbitary piece of memory as a rectangular texture * (including the front or back buffer). */ -static void set_tex_rect_source( struct intel_context *intel, - GLuint offset, - GLuint width, - GLuint height, - GLuint pitch, - GLuint textureFormat ) +static GLboolean set_tex_rect_source( struct intel_context *intel, + GLuint buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, + GLenum type) { - GLint numLevels = 1; + struct i830_context *i830 = i830_context(&intel->ctx); GLuint *setup = i830->meta.Tex[0]; + GLint numLevels = 1; + GLuint textureFormat; + GLuint cpp; - pitch *= i830->intel.intelScreen->cpp; + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } -/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ -/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset); setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((width - 1) << TM0S1_WIDTH_SHIFT) | + ((pitch - 1) << TM0S1_WIDTH_SHIFT) | textureFormat); - setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); + setup[I830_TEXREG_TM0S2] = (((((pitch * cpp) / 4) - 1) << TM0S2_PITCH_SHIFT)); setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; @@ -244,35 +294,13 @@ static void set_tex_rect_source( struct intel_context *intel, TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); i830->meta.emitted &= ~I830_UPLOAD_TEX(0); -} - - -/* Select between front and back draw buffers. - */ -static void set_draw_offset( struct intel_context *intel, - GLuint offset ) -{ -/* i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - -/* Setup an arbitary draw format, useful for targeting - * texture or agp memory. - */ -static void set_draw_format( struct intel_context *intel, - GLuint format, - GLuint depth_format) -{ - i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - format | - DEPTH_IS_Z | - depth_format); + return GL_TRUE; } static void set_vertex_format( struct intel_context *intel ) { + struct i830_context *i830 = i830_context(&intel->ctx); i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | VFT0_TEX_COUNT(1) | VFT0_DIFFUSE | @@ -287,6 +315,113 @@ static void set_vertex_format( struct intel_context *intel ) } +static void meta_import_pixel_state( struct intel_context *intel ) +{ +#if 0 + struct i830_context *i830 = i830_context(&intel->ctx); + memcpy(i830->meta.Fog, i830->state.Fog, I830_FOG_SETUP_SIZE * 4); + + i830->meta.Ctx[I830_CTXREG_LIS5] = i830->state.Ctx[I830_CTXREG_LIS5]; + i830->meta.Ctx[I830_CTXREG_LIS6] = i830->state.Ctx[I830_CTXREG_LIS6]; + i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; + i830->meta.Ctx[I830_CTXREG_IAB] = i830->state.Ctx[I830_CTXREG_IAB]; + + i830->meta.Buffer[I830_DESTREG_SENABLE] = i830->state.Buffer[I830_DESTREG_SENABLE]; + i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; + i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; + + i830->meta.emitted &= ~I830_UPLOAD_FOG; + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; + i830->meta.emitted &= ~I830_UPLOAD_CTX; +#endif +} + + + +/* Select between front and back draw buffers. + */ +static void meta_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint format; + GLuint depth_format = DEPTH_FRMT_16_FIXED; + + intel_region_release(intel, &i830->meta.draw_region); + intel_region_reference(&i830->meta.draw_region, draw_region); + + intel_region_release(intel, &i830->meta.depth_region); + intel_region_reference(&i830->meta.depth_region, depth_region); + + /* XXX: 555 support? + */ + if (draw_region->cpp == 2) + format = DV_PF_565; + else + format = DV_PF_8888; + + if (depth_region) { + if (depth_region->cpp == 2) + depth_format = DEPTH_FRMT_16_FIXED; + else + depth_format = DEPTH_FRMT_24_FIXED_8_OTHER; + } + + i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + format | + DEPTH_IS_Z | + depth_format); + + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void install_meta_state( struct intel_context *intel ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); + + i830->meta.active = ACTIVE; + i830->meta.emitted = 0; + + SET_STATE(i830, meta); + set_vertex_format(intel); + set_no_texture(intel); +} + +static void leave_meta_state( struct intel_context *intel ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + intel_region_release(intel, &i830->meta.draw_region); + intel_region_release(intel, &i830->meta.depth_region); +/* intel_region_release(intel, &i830->meta.tex_region[0]); */ + SET_STATE(i830, state); +} + + + +void i830InitMetaFuncs( struct i830_context *i830 ) +{ + i830->intel.vtbl.install_meta_state = install_meta_state; + i830->intel.vtbl.leave_meta_state = leave_meta_state; + i830->intel.vtbl.meta_no_depth_stencil_write = set_no_depth_stencil_write; + i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; + i830->intel.vtbl.meta_color_mask = set_color_mask; + i830->intel.vtbl.meta_no_texture = set_no_texture; + i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; + i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; + i830->intel.vtbl.meta_draw_region = meta_draw_region; + i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} + + diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index f810bd1bd7a..a5fd0e197bf 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -44,7 +44,7 @@ static void i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int test = intel_translate_compare_func(func); mask = mask & 0xff; @@ -69,7 +69,7 @@ i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, static void i830StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); @@ -86,7 +86,7 @@ static void i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int fop, dfop, dpop; if (INTEL_DEBUG&DEBUG_DRI) @@ -193,7 +193,7 @@ i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; GLuint refInt; @@ -221,7 +221,7 @@ static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) */ static void i830EvalLogicOpBlendState(GLcontext *ctx) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); I830_STATECHANGE(i830, I830_UPLOAD_CTX); @@ -245,7 +245,7 @@ static void i830EvalLogicOpBlendState(GLcontext *ctx) static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); GLubyte r, g, b, a; if (INTEL_DEBUG&DEBUG_DRI) @@ -268,7 +268,7 @@ static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) */ static void i830_set_blend_state( GLcontext * ctx ) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int funcA; int funcRGB; int eqnA; @@ -406,7 +406,7 @@ static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, static void i830DepthFunc(GLcontext *ctx, GLenum func) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int test = intel_translate_compare_func(func); if (INTEL_DEBUG&DEBUG_DRI) @@ -420,7 +420,7 @@ static void i830DepthFunc(GLcontext *ctx, GLenum func) static void i830DepthMask(GLcontext *ctx, GLboolean flag) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); @@ -443,7 +443,7 @@ static void i830DepthMask(GLcontext *ctx, GLboolean flag) */ static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); const GLubyte *m = mask; GLubyte p[4]; int i,j,k; @@ -496,7 +496,7 @@ static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) static void i830Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); intelScreenPrivate *screen = i830->intel.intelScreen; int x1, y1, x2, y2; @@ -530,7 +530,7 @@ static void i830Scissor(GLcontext *ctx, GLint x, GLint y, static void i830LogicOp(GLcontext *ctx, GLenum opcode) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); int tmp = intel_translate_logic_op( opcode ); if (INTEL_DEBUG&DEBUG_DRI) @@ -545,7 +545,7 @@ static void i830LogicOp(GLcontext *ctx, GLenum opcode) static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); GLuint mode; if (INTEL_DEBUG&DEBUG_DRI) @@ -573,7 +573,7 @@ static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) { - i830ContextPtr i830 = I830_CONTEXT( ctx ); + struct i830_context *i830 = i830_context( ctx ); int width; int state5; @@ -594,7 +594,7 @@ static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) static void i830PointSize(GLcontext *ctx, GLfloat size) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); GLint point_size = (int)size; if (INTEL_DEBUG&DEBUG_DRI) @@ -616,7 +616,7 @@ static void i830ColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - i830ContextPtr i830 = I830_CONTEXT( ctx ); + struct i830_context *i830 = i830_context( ctx ); GLuint tmp = 0; if (INTEL_DEBUG&DEBUG_DRI) @@ -638,7 +638,7 @@ static void i830ColorMask(GLcontext *ctx, static void update_specular( GLcontext *ctx ) { - i830ContextPtr i830 = I830_CONTEXT( ctx ); + struct i830_context *i830 = i830_context( ctx ); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; @@ -664,7 +664,7 @@ static void i830LightModelfv(GLcontext *ctx, GLenum pname, */ static void i830ShadeModel(GLcontext *ctx, GLenum mode) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); I830_STATECHANGE(i830, I830_UPLOAD_CTX); @@ -690,7 +690,7 @@ static void i830ShadeModel(GLcontext *ctx, GLenum mode) */ static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); @@ -710,7 +710,7 @@ static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) { - i830ContextPtr i830 = I830_CONTEXT(ctx); + struct i830_context *i830 = i830_context(ctx); switch(cap) { case GL_LIGHTING: @@ -844,7 +844,7 @@ static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) } -static void i830_init_packets( i830ContextPtr i830 ) +static void i830_init_packets( struct i830_context *i830 ) { intelScreenPrivate *screen = i830->intel.intelScreen; @@ -1067,7 +1067,7 @@ void i830InitStateFuncs( struct dd_function_table *functions ) functions->StencilOpSeparate = i830StencilOpSeparate; } -void i830InitState( i830ContextPtr i830 ) +void i830InitState( struct i830_context *i830 ) { GLcontext *ctx = &i830->intel.ctx; diff --git a/src/mesa/drivers/dri/i915/i830_tex.c b/src/mesa/drivers/dri/i915/i830_tex.c index 56b2b92bde3..a230eb2e46e 100644 --- a/src/mesa/drivers/dri/i915/i830_tex.c +++ b/src/mesa/drivers/dri/i915/i830_tex.c @@ -45,261 +45,12 @@ - -/** - * Set the texture wrap modes. - * - * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel - * drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - * - * \param t Texture object whose wrap modes are to be set - * \param swrap Wrap mode for the \a s texture coordinate - * \param twrap Wrap mode for the \a t texture coordinate - */ -static void i830SetTexWrapping(i830TextureObjectPtr tex, - GLenum swrap, - GLenum twrap) -{ - tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK); - - switch( swrap ) { - case GL_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP); - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP); - break; - case GL_CLAMP_TO_BORDER: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER); - break; - case GL_MIRRORED_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR); - break; - default: - break; - } - - switch( twrap ) { - case GL_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP); - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP); - break; - case GL_CLAMP_TO_BORDER: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER); - break; - case GL_MIRRORED_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR); - break; - default: - break; - } -} - - -/** - * Set the texture magnification and minification modes. - * - * \param t Texture whose filter modes are to be set - * \param minf Texture minification mode - * \param magf Texture magnification mode - * \param bias LOD bias for this texture unit. - */ - -static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf, - GLfloat maxanisotropy ) -{ - int minFilt = 0, mipFilt = 0, magFilt = 0; - - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if ( maxanisotropy > 1.0 ) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (minf) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - break; - } - - switch (magf) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - break; - } - } - - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | - (mipFilt << TM0S3_MIP_FILTER_SHIFT) | - (magFilt << TM0S3_MAG_FILTER_SHIFT)); -} - -static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) -{ - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - t->Setup[I830_TEXREG_TM0S4] = - INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]); -} - - -/** - * Allocate space for and load the mesa images into the texture memory block. - * This will happen before drawing with a new texture, or drawing with a - * texture after it was swapped out or teximaged again. - */ - -intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj ) -{ - i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object ); - if ( !t ) - return NULL; - - texObj->DriverData = t; - t->intel.base.tObj = texObj; - t->intel.dirty = ~0; - make_empty_list( &t->intel.base ); - - t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */ - t->Setup[I830_TEXREG_TM0S0] = 0; - t->Setup[I830_TEXREG_TM0S1] = 0; - t->Setup[I830_TEXREG_TM0S2] = 0; - t->Setup[I830_TEXREG_TM0S3] = 0; - t->Setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_NORMAL | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - - i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT ); - i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter, - texObj->MaxAnisotropy ); - i830SetTexBorderColor( t, texObj->_BorderChan ); - - return &t->intel; -} - - -static void i830TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; - if (!t) - return; - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter, - tObj->MaxAnisotropy); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); - break; - - case GL_TEXTURE_BORDER_COLOR: - i830SetTexBorderColor( t, tObj->_BorderChan ); - break; - - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - /* The i830 and its successors can do a lot of this without - * reloading the textures. A project for someone? - */ - intelFlush( ctx ); - driSwapOutTextureObject( (driTextureObject *) t ); - break; - - default: - return; - } - - t->intel.dirty = ~0; -} - - static void i830TexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { - i830ContextPtr i830 = I830_CONTEXT( ctx ); - GLuint unit = ctx->Texture.CurrentUnit; switch (pname) { case GL_TEXTURE_ENV_COLOR: -#if 0 - { - GLubyte r, g, b, a; - GLuint col; - - UNCLAMPED_FLOAT_TO_UBYTE(r, param[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, param[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, param[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, param[ACOMP]); - - col = ((a << 24) | (r << 16) | (g << 8) | b); - - if (col != i830->state.TexEnv[unit][I830_TEXENVREG_COL1]) { - I830_STATECHANGE(i830, I830_UPLOAD_TEXENV); - i830->state.TexEnv[unit][I830_TEXENVREG_COL1] = col; - } - - break; - } -#endif case GL_TEXTURE_ENV_MODE: case GL_COMBINE_RGB: case GL_COMBINE_ALPHA: @@ -320,13 +71,13 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, break; case GL_TEXTURE_LOD_BIAS: { + struct i830_context *i830 = i830_context( ctx ); + GLuint unit = ctx->Texture.CurrentUnit; int b = (int) ((*param) * 16.0); if (b > 63) b = 63; if (b < -64) b = -64; I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; - i830->state.Tex[unit][I830_TEXREG_TM0S3] |= - ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); + i830->lodbias_tm0s3[unit] = ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); break; } @@ -341,5 +92,4 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, void i830InitTextureFuncs( struct dd_function_table *functions ) { functions->TexEnv = i830TexEnv; - functions->TexParameter = i830TexParameter; } diff --git a/src/mesa/drivers/dri/i915/i830_texblend.c b/src/mesa/drivers/dri/i915/i830_texblend.c index 19560868963..13b9c41219c 100644 --- a/src/mesa/drivers/dri/i915/i830_texblend.c +++ b/src/mesa/drivers/dri/i915/i830_texblend.c @@ -132,7 +132,7 @@ static inline GLuint GetTexelOp(GLint unit) * partial support for the extension? */ GLuint -i830SetTexEnvCombine(i830ContextPtr i830, +i830SetTexEnvCombine(struct i830_context *i830, const struct gl_tex_env_combine_state * combine, GLint blendUnit, GLuint texel_op, @@ -394,7 +394,7 @@ i830SetTexEnvCombine(i830ContextPtr i830, } -static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, +static void emit_texblend( struct i830_context *i830, GLuint unit, GLuint blendUnit, GLboolean last_stage ) { struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; @@ -423,7 +423,7 @@ static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); } -static void emit_passthrough( i830ContextPtr i830 ) +static void emit_passthrough( struct i830_context *i830 ) { GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; GLuint unit = 0; @@ -442,7 +442,7 @@ static void emit_passthrough( i830ContextPtr i830 ) I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); } -void i830EmitTextureBlend( i830ContextPtr i830 ) +void i830EmitTextureBlend( struct i830_context *i830 ) { GLcontext *ctx = &i830->intel.ctx; GLuint unit, last_stage = 0, blendunit = 0; diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index d248eba2964..0883b3d29e8 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -38,432 +38,266 @@ #include "intel_screen.h" #include "intel_ioctl.h" #include "intel_tex.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" #include "i830_context.h" #include "i830_reg.h" -static const GLint initial_offsets[6][2] = { {0,0}, - {0,2}, - {1,0}, - {1,2}, - {1,1}, - {1,3} }; -static const GLint step_offsets[6][2] = { {0,2}, - {0,2}, - {-1,2}, - {-1,2}, - {-1,1}, - {-1,1} }; -#define I830_TEX_UNIT_ENABLED(unit) (1<DriverData; - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint firstLevel, lastLevel, numLevels; - - switch( baseImage->TexFormat->MesaFormat ) { + switch (mesa_format) { case MESA_FORMAT_L8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_L8; - break; - + return MAPSURF_8BIT | MT_8BIT_L8; case MESA_FORMAT_I8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; - break; - + return MAPSURF_8BIT | MT_8BIT_I8; case MESA_FORMAT_A8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; /* Kludge -- check with conform, glean */ - break; - + return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ case MESA_FORMAT_AL88: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; - break; - + return MAPSURF_16BIT | MT_16BIT_AY88; case MESA_FORMAT_RGB565: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - + return MAPSURF_16BIT | MT_16BIT_RGB565; case MESA_FORMAT_ARGB1555: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - break; - + return MAPSURF_16BIT | MT_16BIT_ARGB1555; case MESA_FORMAT_ARGB4444: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; - break; - + return MAPSURF_16BIT | MT_16BIT_ARGB4444; case MESA_FORMAT_ARGB8888: - t->intel.texelBytes = 4; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - + return MAPSURF_32BIT | MT_32BIT_ARGB8888; case MESA_FORMAT_YCBCR_REV: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL | - TM0S1_COLORSPACE_CONVERSION); - break; - + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); case MESA_FORMAT_YCBCR: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */ - TM0S1_COLORSPACE_CONVERSION); - break; - + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_COMPRESSED | MT_COMPRESS_FXT1; - break; - + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: - /* - * DXTn pitches are Width/4 * blocksize in bytes - * for DXT1: blocksize=8 so Width/4*8 = Width * 2 - * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 - */ - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - break; + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); case MESA_FORMAT_RGBA_DXT3: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - break; + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); case MESA_FORMAT_RGBA_DXT5: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - break; - + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); default: - fprintf(stderr, "%s: bad image format\n", __FUNCTION__); + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, + mesa_format); abort(); + return 0; } - - /* Compute which mipmap levels we really want to send to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - * Yes, this looks overly complicated, but it's all needed. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - - total_height = dim * 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - if (!t->intel.image[face][i].image) { - fprintf(stderr, "no image %d %d\n", face, i); - break; /* can't happen */ - } - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - default: - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - t->intel.base.dirty_images[0] = ~0; - - for ( total_height = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - if (t->intel.image[0][i].image->IsCompressed) - { - if (t->intel.image[0][i].image->Height > 4) - total_height += t->intel.image[0][i].image->Height/4; - else - total_height += 1; - } - else - total_height += MAX2(2, t->intel.image[0][i].image->Height); - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = total_height*pitch; - t->intel.max_level = i-1; - t->Setup[I830_TEXREG_TM0S1] = - (((tObj->Image[0][firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) | - ((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - t->Setup[I830_TEXREG_TM0S2] = - (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | - TM0S2_CUBE_FACE_ENA_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; - t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; - t->intel.dirty = ~0; - - return intelUploadTexImages( &i830->intel, &t->intel, 0 ); -} - - -static void i830_import_tex_unit( i830ContextPtr i830, - i830TextureObjectPtr t, - GLuint unit ) -{ - if(INTEL_DEBUG&DEBUG_TEXTURE) - fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - - i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; - - I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) ); - - i830->state.Tex[unit][I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << unit) | 4); - i830->state.Tex[unit][I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | - t->intel.TextureOffset); - - i830->state.Tex[unit][I830_TEXREG_TM0S1] = t->Setup[I830_TEXREG_TM0S1]; - i830->state.Tex[unit][I830_TEXREG_TM0S2] = t->Setup[I830_TEXREG_TM0S2]; - - i830->state.Tex[unit][I830_TEXREG_TM0S3] &= TM0S3_LOD_BIAS_MASK; - i830->state.Tex[unit][I830_TEXREG_TM0S3] |= (t->Setup[I830_TEXREG_TM0S3] & - ~TM0S3_LOD_BIAS_MASK); - - i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4]; - i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] & - ~MAP_UNIT_MASK); - i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE]; - i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit); - - t->intel.dirty &= ~(1<Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + switch( wrap ) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP; /* not really correct */ + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - /* Fallback if there's a texture border */ - if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { - fprintf(stderr, "Texture border\n"); - return GL_FALSE; +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean i830_update_tex_unit( struct intel_context *intel, + GLuint unit, + GLuint ss3 ) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; + GLuint *state = i830->state.Tex[unit]; + + memset(state, 0, sizeof(state)); + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj->firstLevel); + + + state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + +/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ +/* t->intel.TextureOffset); */ + + + state[I830_TEXREG_TM0S1] = + (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | + translate_texture_format( firstImage->TexFormat->MesaFormat)); + + state[I830_TEXREG_TM0S2] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - 1) << TM0S2_PITCH_SHIFT) | + TM0S2_CUBE_FACE_ENA_MASK); + + { + if (tObj->Target == GL_TEXTURE_CUBE_MAP) + state[I830_TEXREG_CUBE] = (CUBE_NEGX_ENABLE | + CUBE_POSX_ENABLE | + CUBE_NEGY_ENABLE | + CUBE_POSY_ENABLE | + CUBE_NEGZ_ENABLE | + CUBE_POSZ_ENABLE); + else + state[I830_TEXREG_CUBE] = 0; } - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - if (!i830SetTexImages( i830, tObj )) { + + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: return GL_FALSE; } + + if ( tObj->MaxAnisotropy > 1.0 ) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; + +#if 0 + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; +#endif + + state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - + intelObj->firstLevel)*4) << TM0S3_MIN_MIP_SHIFT; + + state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); } - /* Update state if this is a different texture object to last - * time. - */ - if (i830->intel.CurrentTexObj[unit] != &t->intel || - (t->intel.dirty & (1<WrapS; + GLenum wt = tObj->WrapT; + + + /* 3D textures not available on i830 + */ + if (tObj->Target == GL_TEXTURE_3D) + return GL_FALSE; + + + state[I830_TEXREG_MCS] = ss3; /* TEXCOORDS_ARE_NORMAL */ + + state[I830_TEXREG_MCS] |= (TEXCOORD_ADDR_V_MODE(translate_wrap_mode(ws)) | + TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt))); + + state[I830_TEXREG_MCS] |= MAP_UNIT(unit); } + + state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); - - return GL_TRUE; -} - -static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - - mcs &= ~TEXCOORDS_ARE_NORMAL; - mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - - mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; - mcs |= TEXCOORDS_ARE_NORMAL; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE - | CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE - | CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE; - GLuint face; - - mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; - mcs |= TEXCOORDS_ARE_NORMAL; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = cube; - } - - /* Upload teximages (not pipelined) + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: */ - if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || - t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || - t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { - i830SetTexImages( i830, tObj ); - } - - /* upload (per face) */ - for (face = 0; face < 6; face++) { - if (t->intel.base.dirty_images[face]) { - if (!intelUploadTexImages( &i830->intel, &t->intel, face )) { - return GL_FALSE; - } - } - } - - + I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) ); return GL_TRUE; } -static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - /* This is happening too often. I need to conditionally send diffuse - * state to the card. Perhaps a diffuse dirty flag of some kind. - * Will need to change this logic if more than 2 texture units are - * used. We need to only do this up to the last unit enabled, or unit - * one if nothing is enabled. - */ - - /* The old texture is no longer bound to this texture unit. - * Mark it as such. - */ - i830->intel.CurrentTexObj[unit] = NULL; - - return GL_TRUE; -} - -static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - if (texUnit->_ReallyEnabled && - intel_context(ctx)->intelScreen->tex.size < 2048 * 1024) - return GL_FALSE; - - switch(texUnit->_ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_2d( ctx, unit )); - case TEXTURE_RECT_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_rect( ctx, unit )); - case TEXTURE_CUBE_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_cube( ctx, unit )); - case 0: - return disable_tex( ctx, unit ); - default: - return GL_FALSE; - } -} void i830UpdateTextureState( struct intel_context *intel ) { - i830ContextPtr i830 = I830_CONTEXT(intel); - GLcontext *ctx = &intel->ctx; - GLboolean ok; + struct i830_context *i830 = i830_context(&intel->ctx); + GLboolean ok = GL_TRUE; + GLuint i; - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEX_ALL, GL_FALSE); - - ok = (i830UpdateTexUnit( ctx, 0 ) && - i830UpdateTexUnit( ctx, 1 ) && - i830UpdateTexUnit( ctx, 2 ) && - i830UpdateTexUnit( ctx, 3 )); + for (i = 0 ; i < I830_TEX_UNITS && ok ; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + ok = i830_update_tex_unit( intel, i, TEXCOORDS_ARE_NORMAL ); + break; + case TEXTURE_RECT_BIT: + ok = i830_update_tex_unit( intel, i, TEXCOORDS_ARE_IN_TEXELUNITS ); + break; + case 0: + if (i830->state.active & I830_UPLOAD_TEX(i)) + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); + break; + case TEXTURE_3D_BIT: + default: + ok = GL_FALSE; + break; + } + } FALLBACK( intel, I830_FALLBACK_TEXTURE, !ok ); @@ -473,3 +307,8 @@ void i830UpdateTextureState( struct intel_context *intel ) + + + + + diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 47b53033cbb..249b34db050 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -30,6 +30,7 @@ #include "i830_reg.h" #include "intel_batchbuffer.h" +#include "intel_regions.h" #include "tnl/t_context.h" #include "tnl/t_vertex.h" @@ -62,7 +63,7 @@ do { \ static void i830_render_start( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; - i830ContextPtr i830 = I830_CONTEXT(intel); + struct i830_context *i830 = i830_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint index = tnl->render_inputs; @@ -189,7 +190,7 @@ static void i830_render_start( struct intel_context *intel ) static void i830_reduced_primitive_state( struct intel_context *intel, GLenum rprim ) { - i830ContextPtr i830 = I830_CONTEXT(intel); + struct i830_context *i830 = i830_context(&intel->ctx); GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; st1 &= ~ST1_ENABLE; @@ -220,7 +221,7 @@ static void i830_reduced_primitive_state( struct intel_context *intel, static GLboolean i830_check_vertex_size( struct intel_context *intel, GLuint expected ) { - i830ContextPtr i830 = I830_CONTEXT(intel); + struct i830_context *i830 = i830_context(&intel->ctx); int vft0 = i830->current->Ctx[I830_CTXREG_VF]; int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; @@ -330,13 +331,6 @@ static void i830_emit_invarient_state( struct intel_context *intel ) TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); - 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_VERTEX_TRANSFORM); OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); @@ -366,7 +360,7 @@ do { \ */ static void i830_emit_state( struct intel_context *intel ) { - i830ContextPtr i830 = I830_CONTEXT(intel); + struct i830_context *i830 = i830_context(&intel->ctx); struct i830_hw_state *state = i830->current; int i; GLuint dirty; @@ -374,29 +368,76 @@ static void i830_emit_state( struct intel_context *intel ) dirty = state->active & ~state->emitted; + if (dirty & I830_UPLOAD_INVARIENT) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_INVARIENT:\n"); + i830_emit_invarient_state( intel ); + } + if (dirty & I830_UPLOAD_CTX) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_CTX:\n"); - emit( i830, state->Ctx, sizeof(state->Ctx) ); + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_CTX:\n"); + + BEGIN_BATCH(I830_DEST_SETUP_SIZE+2, 0); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0); + + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0); + + OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); + ADVANCE_BATCH(); } if (dirty & I830_UPLOAD_BUFFERS) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_BUFFERS:\n"); + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_BUFFERS:\n"); emit( i830, state->Buffer, sizeof(state->Buffer) ); } if (dirty & I830_UPLOAD_STIPPLE) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_STIPPLE:\n"); + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_STIPPLE:\n"); emit( i830, state->Stipple, sizeof(state->Stipple) ); } for (i = 0; i < I830_TEX_UNITS; i++) { if ((dirty & I830_UPLOAD_TEX(i))) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i); - emit( i830, state->Tex[i], sizeof(state->Tex[i])); + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i); + + BEGIN_BATCH(I830_TEX_SETUP_SIZE+1, 0); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + BM_MEM_AGP|BM_READ, + state->tex_offset[i] | TM0S0_USE_FENCE); + } + else { + assert(i == 0); + assert(state == &i830->meta); + OUT_BATCH(0); + } + + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); + OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); + OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); } if (dirty & I830_UPLOAD_TEXBLEND(i)) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i); + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i); emit( i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4 ); } @@ -410,46 +451,47 @@ static void i830_destroy_context( struct intel_context *intel ) _tnl_free_vertices(&intel->ctx); } -static void i830_set_draw_offset( struct intel_context *intel, int offset ) +static void i830_set_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) { - i830ContextPtr i830 = I830_CONTEXT(intel); + struct i830_context *i830 = i830_context(&intel->ctx); + + intel_region_release(intel, &i830->state.draw_region); + intel_region_release(intel, &i830->state.depth_region); + intel_region_reference(&i830->state.draw_region, draw_region); + intel_region_reference(&i830->state.depth_region, depth_region); + I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS ); -/* i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ } /* This isn't really handled at the moment. */ static void i830_lost_hardware( struct intel_context *intel ) { - I830_CONTEXT(intel)->state.emitted = 0; + struct i830_context *i830 = i830_context(&intel->ctx); + i830->state.emitted = 0; } -static void i830_emit_flush( struct intel_context *intel ) +static GLuint i830_flush_cmd( void ) { - BATCH_LOCALS; - - BEGIN_BATCH(2, 0); - OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); + return MI_FLUSH | FLUSH_MAP_CACHE; } -void i830InitVtbl( i830ContextPtr i830 ) +void i830InitVtbl( struct i830_context *i830 ) { i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; - i830->intel.vtbl.clear_with_tris = i830ClearWithTris; i830->intel.vtbl.destroy = i830_destroy_context; - i830->intel.vtbl.emit_invarient_state = i830_emit_invarient_state; i830->intel.vtbl.emit_state = i830_emit_state; i830->intel.vtbl.lost_hardware = i830_lost_hardware; i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; - i830->intel.vtbl.set_draw_offset = i830_set_draw_offset; + i830->intel.vtbl.set_draw_region = i830_set_draw_region; i830->intel.vtbl.update_texture_state = i830UpdateTextureState; - i830->intel.vtbl.emit_flush = i830_emit_flush; + i830->intel.vtbl.flush_cmd = i830_flush_cmd; i830->intel.vtbl.render_start = i830_render_start; } diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index cebad623c8e..5e2e2ae7e4b 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -44,6 +44,7 @@ #define I915_UPLOAD_CONSTANTS 0x10 #define I915_UPLOAD_FOG 0x20 #define I915_UPLOAD_INVARIENT 0x40 +#define I915_UPLOAD_DEFAULTS 0x80 #define I915_UPLOAD_TEX(i) (0x00010000<<(i)) #define I915_UPLOAD_TEX_ALL (0x00ff0000) #define I915_UPLOAD_TEX_0_SHIFT 16 @@ -92,6 +93,15 @@ #define I915_TEXREG_SS4 5 #define I915_TEX_SETUP_SIZE 6 +#define I915_DEFREG_C0 0 +#define I915_DEFREG_C1 1 +#define I915_DEFREG_S0 2 +#define I915_DEFREG_S1 3 +#define I915_DEFREG_Z0 4 +#define I915_DEFREG_Z1 5 +#define I915_DEF_SETUP_SIZE 6 + + #define I915_MAX_CONSTANT 32 #define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) @@ -190,6 +200,7 @@ struct i915_hw_state { GLuint Buffer[I915_DEST_SETUP_SIZE]; GLuint Stipple[I915_STP_SETUP_SIZE]; GLuint Fog[I915_FOG_SETUP_SIZE]; + GLuint Defaults[I915_DEF_SETUP_SIZE]; GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; GLuint Constant[I915_CONSTANT_SIZE]; GLuint ConstantSize; diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h index 8936220892b..cd79988a5e7 100644 --- a/src/mesa/drivers/dri/i915/i915_reg.h +++ b/src/mesa/drivers/dri/i915/i915_reg.h @@ -824,6 +824,10 @@ #define ST1_ENABLE (1<<16) #define ST1_MASK (0xffff) +#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) +#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) +#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) + #define MI_FLUSH ((0<<29)|(4<<23)) #define FLUSH_MAP_CACHE (1<<0) diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 2586219b82b..4afc4ec2af2 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -896,6 +896,19 @@ static void i915_init_packets( struct i915_context *i915 ) } +#if 0 + { + I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); + i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; + i915->state.Default[I915_DEFREG_C1] = 0; + i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; + i915->state.Default[I915_DEFREG_S1] = 0; + i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; + i915->state.Default[I915_DEFREG_Z1] = 0; + } +#endif + + /* These will be emitted every at the head of every buffer, unless * we get hardware contexts working. */ diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 014e100bb80..e3e6d06ab29 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -245,7 +245,7 @@ static void i915_emit_state( struct intel_context *intel ) if (dirty & I915_UPLOAD_BUFFERS) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - BEGIN_BATCH(I915_DEST_SETUP_SIZE, 0); + BEGIN_BATCH(I915_DEST_SETUP_SIZE+2, 0); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0); @@ -370,7 +370,6 @@ void i915InitVtbl( struct i915_context *i915 ) { i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; 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; diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 50f75574734..22b595639aa 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -67,9 +67,9 @@ * modifying cliprects ??? */ -static void intel_dump_batchbuffer( unsigned offset, - int *ptr, - int count ) +static void intel_dump_batchbuffer( GLuint offset, + GLuint *ptr, + GLuint count ) { int i; fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count/4); diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h index bacda5437cb..8ac3fadc551 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -113,7 +113,7 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) #define OUT_RELOC(buf,flags,delta) do { \ - assert(delta >= 0); \ + assert((delta) >= 0); \ intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ } while (0) diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 0185d5fda2f..43b52ccd2b2 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -67,6 +67,9 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) * should work regardless. */ LOCK_HARDWARE( intel ); + + if (intel->driDrawable && + intel->driDrawable->numClipRects) { intelScreenPrivate *intelScreen = intel->intelScreen; __DRIdrawablePrivate *dPriv = intel->driDrawable; @@ -117,9 +120,9 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) ADVANCE_BATCH(); } - } - intel->last_swap_fence = intel_batchbuffer_flush( intel->batch ); + intel->last_swap_fence = intel_batchbuffer_flush( intel->batch ); + } UNLOCK_HARDWARE( intel ); } @@ -299,6 +302,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); + + if (intel->driDrawable->numClipRects) { drm_clip_rect_t clear; @@ -367,8 +372,9 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, ADVANCE_BATCH(); } } + intel_batchbuffer_flush( intel->batch ); } - intel_batchbuffer_flush( intel->batch ); + UNLOCK_HARDWARE( intel ); } diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index f3f2d7974aa..47e1a90ded6 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -216,8 +216,6 @@ void intelWindowMoved( struct intel_context *intel ) static void emit_clip_rect_quads(struct intel_context *intel, const drm_clip_rect_t *clear) { - GLuint i; - /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the * drawing origin may not be correctly emitted. */ @@ -243,59 +241,63 @@ static void intelClearWithTris(struct intel_context *intel, drm_clip_rect_t clear; LOCK_HARDWARE(intel); - intel->vtbl.install_meta_state(intel); - if(!all) { - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = cx + cw; - clear.y2 = cy + ch; - } else { - clear.x1 = 0; - clear.y1 = 0; - clear.x2 = dPriv->w; - clear.y2 = dPriv->h; - } + if (intel->driDrawable->numClipRects) { - /* Back and stencil cliprects are the same. Try and do both - * buffers at once: - */ - if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) { - intel->vtbl.meta_draw_region(intel, - intel->back_region, - intel->depth_region ); + intel->vtbl.install_meta_state(intel); - if (mask & BUFFER_BIT_BACK_LEFT) - intel->vtbl.meta_color_mask(intel, GL_TRUE ); - else - intel->vtbl.meta_color_mask(intel, GL_FALSE ); + if(!all) { + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; + } else { + clear.x1 = 0; + clear.y1 = 0; + clear.x2 = dPriv->w; + clear.y2 = dPriv->h; + } - if (mask & BUFFER_BIT_STENCIL) - intel->vtbl.meta_stencil_replace( intel, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - else - intel->vtbl.meta_no_depth_stencil_write(intel); - - /* Do cliprects explicitly: + /* Back and stencil cliprects are the same. Try and do both + * buffers at once: */ - emit_clip_rect_quads(intel, &clear); + if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) { + intel->vtbl.meta_draw_region(intel, + intel->back_region, + intel->depth_region ); + + if (mask & BUFFER_BIT_BACK_LEFT) + intel->vtbl.meta_color_mask(intel, GL_TRUE ); + else + intel->vtbl.meta_color_mask(intel, GL_FALSE ); + + if (mask & BUFFER_BIT_STENCIL) + intel->vtbl.meta_stencil_replace( intel, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + else + intel->vtbl.meta_no_depth_stencil_write(intel); + + /* Do cliprects explicitly: + */ + emit_clip_rect_quads(intel, &clear); + } + + /* Front may have different cliprects: + */ + if (mask & BUFFER_BIT_FRONT_LEFT) { + intel->vtbl.meta_no_depth_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE ); + intel->vtbl.meta_draw_region(intel, + intel->front_region, + intel->depth_region); + + emit_clip_rect_quads(intel, &clear); + } + + intel->vtbl.leave_meta_state( intel ); + intel_batchbuffer_flush( intel->batch ); } - - /* Front may have different cliprects: - */ - if (mask & BUFFER_BIT_FRONT_LEFT) { - intel->vtbl.meta_no_depth_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_TRUE ); - intel->vtbl.meta_draw_region(intel, - intel->front_region, - intel->depth_region); - - emit_clip_rect_quads(intel, &clear); - } - - intel->vtbl.leave_meta_state( intel ); - intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE(intel); } diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index e27d1cccddb..9b36b767f6c 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -113,7 +113,6 @@ struct intel_context struct { void (*destroy)( struct intel_context *intel ); void (*emit_state)( struct intel_context *intel ); - void (*emit_invarient_state)( struct intel_context *intel ); void (*lost_hardware)( struct intel_context *intel ); void (*update_texture_state)( struct intel_context *intel ); @@ -128,10 +127,6 @@ struct intel_context GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected ); - void (*clear_with_tris)( struct intel_context *intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch); - /* Metaops: */ diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c index 5511ddd007d..f8b8373133b 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -66,6 +66,7 @@ GLboolean intel_check_meta_tex_fragment_ops( GLcontext *ctx ) * fragment programs on i915. */ return !(ctx->_ImageTransferState || + ctx->Fog.Enabled || /* not done yet */ ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); } diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c index c4e46bab451..fa4e2bdc0eb 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -91,6 +91,34 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, if (!src || !dst || type != GL_COLOR) return GL_FALSE; + /* Can't handle overlapping regions. Don't have sufficient control + * over rasterization to pull it off in-place. Punt on these for + * now. + * + * XXX: do a copy to a temporary. + */ + { + drm_clip_rect_t src; + drm_clip_rect_t dst; + drm_clip_rect_t tmp; + + src.x1 = srcx; + src.y1 = srcy; + src.x2 = srcx + width; + src.y2 = srcy + height; + + dst.x1 = dstx; + dst.y1 = dsty; + dst.x1 = dstx + width * ctx->Pixel.ZoomX; + dst.y2 = dsty + height * ctx->Pixel.ZoomY; + + + if (intel_intersect_cliprects(&tmp, &src, &dst)) { + _mesa_printf("%s: regions overlap\n", __FUNCTION__); + return GL_FALSE; + } + } + intelFlush( &intel->ctx ); intel->vtbl.install_meta_state(intel); @@ -131,7 +159,8 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, LOCK_HARDWARE( intel ); - + + if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; @@ -171,11 +200,11 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, 0x00ff00ff, srcx, srcx+width, srcy, srcy+height); - } - out: - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } UNLOCK_HARDWARE( intel ); return GL_TRUE; } @@ -215,6 +244,8 @@ static GLboolean do_blit_copypixels( GLcontext *ctx, intel->vtbl.emit_state(intel); LOCK_HARDWARE( intel ); + + if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; drm_clip_rect_t *box = dPriv->pClipRects; @@ -279,9 +310,10 @@ static GLboolean do_blit_copypixels( GLcontext *ctx, rect.x2 - rect.x1, rect.y2 - rect.y1 ); } + + out: + intel_batchbuffer_flush( intel->batch ); } - out: - intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE( intel ); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c index ea3ca113eb7..b7a97a7dc9d 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -136,6 +136,7 @@ static GLboolean do_texture_drawpixels( GLcontext *ctx, LOCK_HARDWARE( intel ); + if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; GLint srcx, srcy; @@ -174,11 +175,10 @@ static GLboolean do_texture_drawpixels( GLcontext *ctx, 0x00ff00ff, srcx, srcx+width, srcy+height, srcy); + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); } - - out: - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); UNLOCK_HARDWARE( intel ); _mesa_printf("%s - DONE\n", __FUNCTION__); return GL_TRUE; @@ -215,7 +215,7 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); GLuint src_offset; GLuint rowLength; - GLuint fence; + GLuint fence = 0; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -283,6 +283,8 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); + + if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; @@ -314,12 +316,12 @@ static GLboolean do_blit_drawpixels( GLcontext *ctx, rect.x2 - rect.x1, rect.y2 - rect.y1 ); } + fence = intel_batchbuffer_flush( intel->batch ); } - - fence = intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE( intel ); - bmFinishFence(intel->bm, fence); + if (intel->driDrawable->numClipRects) + bmFinishFence(intel->bm, fence); _mesa_printf("%s - DONE\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c index ec993206d1f..bdd8c74f2cb 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -110,49 +110,52 @@ do_texture_readpixels( GLcontext *ctx, } LOCK_HARDWARE( intel ); - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_stencil_write(intel); - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE( intel ); + SET_STATE(i830, state); + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source( intel, + src_region, + textureFormat ); + + + intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat ); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, + x, x+width, + y, y+height ); + + intel->vtbl.leave_meta_state(intel); } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source( intel, - src_region, - textureFormat ); - - - intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat ); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, - x, x+width, - y, y+height ); - - intel->vtbl.leave_meta_state(intel); UNLOCK_HARDWARE( intel ); intel_region_wait_fence( ctx, dest_region ); /* required by GL */ @@ -176,7 +179,7 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; - GLuint fence; + GLuint fence = 0; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -237,6 +240,8 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, */ intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); + + if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; @@ -274,10 +279,12 @@ static GLboolean do_blit_readpixels( GLcontext *ctx, } UNLOCK_HARDWARE( intel ); - bmFinishFence(intel->bm, fence); + if (intel->driDrawable->numClipRects) + bmFinishFence(intel->bm, fence); if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s - DONE\n", __FUNCTION__); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 3dfad52cd1c..075b453848b 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -111,7 +111,7 @@ static void intelDmaPrimitive( struct intel_context *intel, GLenum prim ) if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); INTEL_FIREVERTICES(intel); intel->vtbl.reduced_primitive_state( intel, reduced_prim[prim] ); - intelStartInlinePrimitive( intel, hw_prim[prim] ); + intelStartInlinePrimitive( intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS ); } @@ -120,10 +120,15 @@ static void intelDmaPrimitive( struct intel_context *intel, GLenum prim ) do { \ intelDmaPrimitive( intel, prim ); \ } while (0) -#define FLUSH() INTEL_FIREVERTICES( intel ) + +#define FLUSH() \ +do { \ + if (intel->prim.flush) \ + intel->prim.flush(intel); \ +} while (0) #define GET_SUBSEQUENT_VB_MAX_VERTS() \ - (((intel->alloc.size / 2) - 1500) / (intel->vertex_size*4)) + ((BATCH_SZ - 1500) / (intel->vertex_size*4)) #define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() #define ALLOC_VERTS( nr ) \ @@ -199,10 +204,6 @@ static GLboolean intel_run_render( GLcontext *ctx, struct vertex_buffer *VB = &tnl->vb; GLuint i; - /* disabled - */ - return GL_TRUE; - /* Don't handle clipping or indexed vertices. */ if (intel->RenderIndex != 0 || @@ -229,6 +230,9 @@ static GLboolean intel_run_render( GLcontext *ctx, } tnl->Driver.Render.Finish( ctx ); + + if (intel->prim.flush) + intel->prim.flush(intel); return GL_FALSE; /* finished the pipe */ } diff --git a/src/mesa/drivers/dri/i915/intel_tex_copy.c b/src/mesa/drivers/dri/i915/intel_tex_copy.c index ea311eb0c08..3394ea649f8 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_copy.c +++ b/src/mesa/drivers/dri/i915/intel_tex_copy.c @@ -83,7 +83,6 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, { GLcontext *ctx = &intel->ctx; struct intel_region *src = get_teximage_source(intel, internalFormat); - GLuint ret = GL_TRUE; if (!intelImage->mt || !src) return GL_FALSE; @@ -99,51 +98,45 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, GLint orig_y = y; GLuint window_y; - if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { - ret = GL_TRUE; - goto out; + if (intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { + /* Update dst for clipped src. Need to also clip the source rect. + */ + dstx += x - orig_x; + dsty += y - orig_y; + + x += dPriv->x; + + window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); + + y = window_y + y; + + + + /* A bit of fiddling to get the blitter to work with -ve + * pitches. But we get a nice inverted blit this way, so it's + * worth it: + */ + intelEmitCopyBlit( intel, + intelImage->mt->cpp, + + -src->pitch, + src->buffer, + src->height * src->pitch * src->cpp, + + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + + x, y + height, + dstx, dsty, + width, height ); + + intel_batchbuffer_flush( intel->batch ); } - - /* Update dst for clipped src. Need to also clip the source rect. - */ - dstx += x - orig_x; - dsty += y - orig_y; - - x += dPriv->x; - - window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); - - y = window_y + y; - - - - /* A bit of fiddling to get the blitter to work with -ve - * pitches. But we get a nice inverted blit this way, so it's - * worth it: - */ - intelEmitCopyBlit( intel, - intelImage->mt->cpp, - - -src->pitch, - src->buffer, - src->height * src->pitch * src->cpp, - - intelImage->mt->pitch, - intelImage->mt->region->buffer, - image_offset, - - x, y + height, - dstx, dsty, - width, height ); - - out: - intel_batchbuffer_flush( intel->batch ); } UNLOCK_HARDWARE(intel); - if (!ret) - return GL_FALSE; #if 0 /* GL_SGIS_generate_mipmap -- this can be accelerated now. diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index f8aaf995ca6..ff22f142422 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -48,20 +48,7 @@ static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ); static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); -/* The simplest but least-good technique for integrating new buffer - * management: - * - * LOCK_HARDWARE - * validate_buffers - * emit_state to batch - * emit_vertices to batch - * flush batch - * fence_buffers - * UNLOCK_HARDWARE - * - * Will look later at ways to get the emit_state and emit_vertices out - * of the locked region - vertex buffers, second batch buffer for - * primitives, relocation fixups for texture addresses. +/* */ static void intel_flush_inline_primitive( struct intel_context *intel ) { @@ -581,6 +568,9 @@ intel_fallback_tri( struct intel_context *intel, if (0) fprintf(stderr, "\n%s\n", __FUNCTION__); + + if (intel->prim.flush) + intel->prim.flush(intel); _swsetup_Translate( ctx, v0, &v[0] ); _swsetup_Translate( ctx, v1, &v[1] ); @@ -602,6 +592,9 @@ intel_fallback_line( struct intel_context *intel, if (0) fprintf(stderr, "\n%s\n", __FUNCTION__); + if (intel->prim.flush) + intel->prim.flush(intel); + _swsetup_Translate( ctx, v0, &v[0] ); _swsetup_Translate( ctx, v1, &v[1] ); intelSpanRenderStart( ctx ); @@ -610,8 +603,6 @@ intel_fallback_line( struct intel_context *intel, } - - /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ @@ -742,7 +733,6 @@ void intelChooseRenderState(GLcontext *ctx) intel->draw_tri = intel_draw_triangle; } -#if 0 /* Hook in fallbacks for specific primitives. */ if (flags & ANY_FALLBACK_FLAGS) @@ -758,8 +748,6 @@ void intelChooseRenderState(GLcontext *ctx) index |= INTEL_FALLBACK_BIT; } -#endif - } if (intel->RenderIndex != index) {