From 7843243deedd66b0c94c8874e732ed7e8c6617ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 07:58:25 -0600 Subject: st: also check _NEW_PROGRAM flag for vertex shader constant buffers This is a follow-on to commit c1a3b852807fb160f0cd246c1364b7336b4b947e. Note that (at this time) wherever _NEW_PROGRAM_CONSTANTS is set we're still setting _NEW_PROGRAM so this won't really make any difference (for now). --- src/mesa/state_tracker/st_atom_constbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 77ecd0719e..3ba7b26928 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -105,7 +105,7 @@ static void update_vs_constants(struct st_context *st ) const struct st_tracked_state st_update_vs_constants = { "st_update_vs_constants", /* name */ { /* dirty */ - _NEW_PROGRAM_CONSTANTS, + (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS), /* mesa */ ST_NEW_VERTEX_PROGRAM, /* st */ }, update_vs_constants /* update */ -- cgit v1.2.3 From f48473e42511f8d37a239a07f791bc0a87209e5b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 08:59:47 -0600 Subject: r200/r300/r500: add _NEW_PROGRAM_CONSTANTS flag Make sure we detect constant buffer changes indicated by the new flag. Should be able to remove _NEW_PROGRAM (and _NEW_MODELVIEW, _NEW_LIGHT, etc) from several places (someday. --- src/mesa/drivers/dri/r200/r200_state.c | 3 ++- src/mesa/drivers/dri/r300/r300_fragprog.c | 3 ++- src/mesa/drivers/dri/r300/r300_state.c | 7 ++++--- src/mesa/drivers/dri/r300/r500_fragprog.c | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 2fcc87c0f5..28ba5f49bc 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2484,7 +2484,7 @@ void r200ValidateState( GLcontext *ctx ) r200UpdateDrawBuffer(ctx); } - if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) { + if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) { r200UpdateTextureState( ctx ); new_state |= rmesa->NewGLState; /* may add TEXTURE_MATRIX */ r200UpdateLocalViewer( ctx ); @@ -2523,6 +2523,7 @@ void r200ValidateState( GLcontext *ctx ) } if (new_state & (_NEW_PROGRAM| + _NEW_PROGRAM_CONSTANTS | /* need to test for pretty much anything due to possible parameter bindings */ _NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM| _NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX| diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 873cde4414..2f45429cf2 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -470,7 +470,8 @@ void r300TranslateFragmentShader(r300ContextPtr r300, fp->translated = GL_TRUE; if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) r300FragmentProgramDump(fp, &fp->code); - r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM); + r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM | + _NEW_PROGRAM_CONSTANTS); } update_params(r300, fp); diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 8095538ff9..2589f09cc8 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1107,7 +1107,7 @@ void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) struct gl_program_parameter_list *paramList; GLuint i; - if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM))) + if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))) return; fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current; @@ -2355,11 +2355,12 @@ void r300UpdateShaders(r300ContextPtr rmesa) hw_tcl_on = future_hw_tcl_on = 0; r300ResetHwState(rmesa); - r300UpdateStateParameters(ctx, _NEW_PROGRAM); + r300UpdateStateParameters(ctx, _NEW_PROGRAM | + _NEW_PROGRAM_CONSTANTS); return; } } - r300UpdateStateParameters(ctx, _NEW_PROGRAM); + r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); } static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c index 292573de89..300559d0b4 100644 --- a/src/mesa/drivers/dri/r300/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/r500_fragprog.c @@ -501,7 +501,8 @@ void r500TranslateFragmentShader(r300ContextPtr r300, _mesa_reference_program(r300->radeon.glCtx, &compiler.program, 0); - r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM); + r300UpdateStateParameters(r300->radeon.glCtx, _NEW_PROGRAM | + _NEW_PROGRAM_CONSTANTS); if (RADEON_DEBUG & DEBUG_PIXEL) { if (fp->translated) { -- cgit v1.2.3 From 817dcdd280cd749c3186bd3f00c06f41270aa884 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:07:02 -0600 Subject: i965: use new _NEW_PROGRAM_CONSTANTS flag instead of dynamic flags --- src/mesa/drivers/dri/i965/brw_curbe.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 18b187ed1d..3c81899672 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -188,13 +188,6 @@ static void prepare_constant_buffer(struct brw_context *brw) GLfloat *buf; GLuint i; - /* Update our own dependency flags. This works because this - * function will also be called whenever fp or vp changes. - */ - brw->curbe.tracked_state.dirty.mesa = (_NEW_TRANSFORM|_NEW_PROJECTION); - brw->curbe.tracked_state.dirty.mesa |= vp->program.Base.Parameters->StateFlags; - brw->curbe.tracked_state.dirty.mesa |= fp->program.Base.Parameters->StateFlags; - if (sz == 0) { if (brw->curbe.last_buf) { free(brw->curbe.last_buf); @@ -422,7 +415,7 @@ static void emit_constant_buffer(struct brw_context *brw) */ const struct brw_tracked_state brw_constant_buffer = { .dirty = { - .mesa = (_NEW_TRANSFORM|_NEW_PROJECTION), /* plus fp and vp flags */ + .mesa = _NEW_PROGRAM_CONSTANTS, .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_VERTEX_PROGRAM | BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */ -- cgit v1.2.3 From 6b6a23c0f7e042d71764a2028f3d33b59076ac7c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:07:46 -0600 Subject: i965: updates to some debug code --- src/mesa/drivers/dri/i965/brw_curbe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 3c81899672..da746e4aa0 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -352,11 +352,7 @@ update_constant_buffer(struct brw_context *brw, dri_bo_unmap(const_buffer); if (0) { - int i; - for (i = 0; i < params->NumParameters; i++) { - float *p = params->ParameterValues[i]; - printf("%d: %f %f %f %f\n", i, p[0], p[1], p[2], p[3]); - } + _mesa_print_parameter_list(params); } } } @@ -369,7 +365,7 @@ update_vertex_constant_buffer(struct brw_context *brw) struct brw_vertex_program *vp = (struct brw_vertex_program *) brw->vertex_program; if (0) { - printf("update VS constants in buffer %p\n", vp->const_buffer); + printf("update VS constants in buffer %p vp = %p\n", vp->const_buffer, vp); printf("program %u\n", vp->program.Base.Id); } update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); @@ -382,6 +378,10 @@ update_fragment_constant_buffer(struct brw_context *brw) { struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; + if (0) { + printf("update WM constants in buffer %p\n", fp->const_buffer); + printf("program %u\n", fp->program.Base.Id); + } update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); } -- cgit v1.2.3 From 1dbab84e21cad81e971265db3dbc8dc6c344b340 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:14:16 -0600 Subject: i965: use _NEW_PROGRAM_CONSTANTS and always create new const buffers When program constants change we create a new VS constant buffer instead of re-using the old one. This allows us to have several const buffers in flight with vertex rendering. --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 71840d1e4e..89c456e62c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -456,17 +456,14 @@ brw_update_vs_constant_surface( GLcontext *ctx, assert(surf == 0); - /* free old const buffer if too small */ - if (const_buffer && const_buffer->size < size) { - dri_bo_unreference(const_buffer); - const_buffer = NULL; - } + /* We always create a new VS constant buffer so that several can be + * in flight at a time. Free the old one first... + */ + dri_bo_unreference(const_buffer); - /* alloc new buffer if needed */ - if (!const_buffer) { - const_buffer = - drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", size, 64); - } + /* alloc new buffer */ + const_buffer = + drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", size, 64); memset(&key, 0, sizeof(key)); @@ -783,8 +780,7 @@ brw_vs_get_binding_table(struct brw_context *brw) /** - * Vertex shader surfaces. Just constant buffer for now. Could add vertex - * shader textures in the future. + * Vertex shader surfaces (constant buffer). */ static void prepare_vs_surfaces(struct brw_context *brw ) { @@ -820,8 +816,12 @@ prepare_surfaces(struct brw_context *brw) const struct brw_tracked_state brw_wm_surfaces = { .dirty = { - .mesa = _NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS | _NEW_PROGRAM, - .brw = BRW_NEW_CONTEXT, + .mesa = (_NEW_COLOR | + _NEW_TEXTURE | + _NEW_BUFFERS | + _NEW_PROGRAM | + _NEW_PROGRAM_CONSTANTS), + .brw = (BRW_NEW_CONTEXT), .cache = 0 }, .prepare = prepare_surfaces, -- cgit v1.2.3 From a36dd5d54e3de5662c694e764d1c49795ddb6814 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:14:53 -0600 Subject: i915: check the new _NEW_PROGRAM_CONSTANT flag --- src/mesa/drivers/dri/i915/i915_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index fdd2cf6109..45ba2d14a5 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -73,7 +73,7 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state) p->params_uptodate = 0; } - if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) + if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) i915_update_fog(ctx); } -- cgit v1.2.3 From e5681fc176bc43bc6c7804bd1e8d8557cdcab345 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:16:21 -0600 Subject: i965: add _NEW_PROGRAM_CONSTANTS to mesa_bits[] list --- src/mesa/drivers/dri/i965/brw_state_upload.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 5de1450e61..197efeb1b7 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -218,6 +218,7 @@ static struct dirty_bit_map mesa_bits[] = { DEFINE_BIT(_NEW_MULTISAMPLE), DEFINE_BIT(_NEW_TRACK_MATRIX), DEFINE_BIT(_NEW_PROGRAM), + DEFINE_BIT(_NEW_PROGRAM_CONSTANTS), {0, 0, 0} }; -- cgit v1.2.3 From f428255bde93a452a7cdd48fba21839c99beb6cb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 09:23:15 -0600 Subject: i965: the brw_constant_buffer state atom is no longer dynamic No more dynamic atoms so we can simplify the state validation code a little. --- src/mesa/drivers/dri/i965/brw_context.h | 7 ------- src/mesa/drivers/dri/i965/brw_state_upload.c | 31 +++++----------------------- 2 files changed, 5 insertions(+), 33 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a0b3b06309..af9fef5e22 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -448,8 +448,6 @@ struct brw_context struct { struct brw_state_flags dirty; - struct brw_tracked_state **atoms; - GLuint nr_atoms; GLuint nr_color_regions; struct intel_region *color_regions[MAX_DRAW_BUFFERS]; @@ -553,11 +551,6 @@ struct brw_context GLuint vs_size; GLuint total_size; - /* Dynamic tracker which changes to reflect the state referenced - * by active fp and vp program parameters: - */ - struct brw_tracked_state tracked_state; - dri_bo *curbe_bo; /** Offset within curbe_bo of space for current curbe entry */ GLuint curbe_offset; diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 197efeb1b7..491e2e2452 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -102,39 +102,18 @@ const struct brw_tracked_state *atoms[] = &brw_indices, &brw_vertices, - NULL, /* brw_constant_buffer */ + &brw_constant_buffer }; void brw_init_state( struct brw_context *brw ) { - GLuint i; - brw_init_cache(brw); - - brw->state.atoms = _mesa_malloc(sizeof(atoms)); - brw->state.nr_atoms = sizeof(atoms)/sizeof(*atoms); - _mesa_memcpy(brw->state.atoms, atoms, sizeof(atoms)); - - /* Patch in a pointer to the dynamic state atom: - */ - for (i = 0; i < brw->state.nr_atoms; i++) - if (brw->state.atoms[i] == NULL) - brw->state.atoms[i] = &brw->curbe.tracked_state; - - _mesa_memcpy(&brw->curbe.tracked_state, - &brw_constant_buffer, - sizeof(brw_constant_buffer)); } void brw_destroy_state( struct brw_context *brw ) { - if (brw->state.atoms) { - _mesa_free(brw->state.atoms); - brw->state.atoms = NULL; - } - brw_destroy_cache(brw); brw_destroy_batch_cache(brw); } @@ -337,7 +316,7 @@ void brw_validate_state( struct brw_context *brw ) /* do prepare stage for all atoms */ for (i = 0; i < Elements(atoms); i++) { - const struct brw_tracked_state *atom = brw->state.atoms[i]; + const struct brw_tracked_state *atom = atoms[i]; if (brw->intel.Fallback) break; @@ -368,8 +347,8 @@ void brw_upload_state(struct brw_context *brw) _mesa_memset(&examined, 0, sizeof(examined)); prev = *state; - for (i = 0; i < brw->state.nr_atoms; i++) { - const struct brw_tracked_state *atom = brw->state.atoms[i]; + for (i = 0; i < Elements(atoms); i++) { + const struct brw_tracked_state *atom = atoms[i]; struct brw_state_flags generated; assert(atom->dirty.mesa || @@ -398,7 +377,7 @@ void brw_upload_state(struct brw_context *brw) } else { for (i = 0; i < Elements(atoms); i++) { - const struct brw_tracked_state *atom = brw->state.atoms[i]; + const struct brw_tracked_state *atom = atoms[i]; if (brw->intel.Fallback) break; -- cgit v1.2.3 From 50853be894aa3edd1e9271f7d625f319209e340f Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 22 Apr 2009 17:37:18 +0200 Subject: intel: fix max anisotropy supported i915 actually supports up to 4 (according to header file - not tested), i965 up to 16 (code already handled this but slightly broken), so don't use 2 for all chips, even though angular dependency is very high. --- src/mesa/drivers/dri/i915/i830_context.c | 2 ++ src/mesa/drivers/dri/i915/i915_context.c | 2 ++ src/mesa/drivers/dri/i965/brw_context.c | 2 ++ src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- src/mesa/drivers/dri/intel/intel_context.c | 2 -- 5 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 10b9bf371c..840946f908 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -98,6 +98,8 @@ i830CreateContext(const __GLcontextModes * mesaVis, ctx->Const.MaxTextureRectSize = (1 << 11); ctx->Const.MaxTextureUnits = I830_TEX_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2.0; + ctx->Const.MaxDrawBuffers = 1; _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index fdd2cf6109..1f9f363df9 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -145,6 +145,8 @@ i915CreateContext(const __GLcontextModes * mesaVis, ctx->Const.MaxTextureRectSize = (1 << 11); ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 4.0; + /* GL_ARB_fragment_program limits - don't think Mesa actually * validates programs against these, and in any case one ARB * instruction can translate to more than one HW instruction, so diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index d96ff29310..4dbe551d83 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -118,6 +118,8 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, ctx->Const.MaxCubeTextureLevels = 12; ctx->Const.MaxTextureRectSize = (1<<12); + ctx->Const.MaxTextureMaxAnisotropy = 16.0; + /* if conformance mode is set, swrast can handle any size AA point */ ctx->Const.MaxPointSizeAA = 255.0; diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 1fc9f01372..c604ef0162 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -152,7 +152,7 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key, sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; if (key->max_aniso > 2.0) { - sampler->ss3.max_aniso = MAX2((key->max_aniso - 2) / 2, + sampler->ss3.max_aniso = MIN2((key->max_aniso - 2) / 2, BRW_ANISORATIO_16); } } diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 3436b8ecd3..9b628dbc8e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -528,8 +528,6 @@ intelInitContext(struct intel_context *intel, } } - ctx->Const.MaxTextureMaxAnisotropy = 2.0; - /* This doesn't yet catch all non-conformant rendering, but it's a * start. */ -- cgit v1.2.3 From a071a8d2e72e52e6a8906448b171756c8920ce96 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 10:44:36 -0600 Subject: i965: remove unused state atom entries --- src/mesa/drivers/dri/i965/brw_state_upload.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 491e2e2452..20892cdf32 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -59,7 +59,6 @@ const struct brw_tracked_state *atoms[] = &brw_curbe_offsets, &brw_recalculate_urb_fence, - &brw_cc_vp, &brw_cc_unit, @@ -88,15 +87,8 @@ const struct brw_tracked_state *atoms[] = &brw_line_stipple, &brw_aa_line_parameters, - /* Ordering of the commands below is documented as fixed. - */ -#if 0 - &brw_pipelined_state_pointers, - &brw_urb_fence, - &brw_constant_buffer_state, -#else + &brw_psp_urb_cbs, -#endif &brw_drawing_rect, &brw_indices, -- cgit v1.2.3 From f9af97c7a5d81226a87d79baf8fb00231c96398d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:08:46 -0600 Subject: i965: checkpoint commit: use two state caches instead of one The new, second cache will only be used for surface-related items. Since we can create many surfaces the original, single cache could get filled quickly. When we cleared it, we had to regenerate shaders, etc. With two caches, we can avoid doing that. --- src/mesa/drivers/dri/i965/brw_context.h | 3 +- src/mesa/drivers/dri/i965/brw_state.h | 4 +- src/mesa/drivers/dri/i965/brw_state_cache.c | 122 ++++++++++++++++++--------- src/mesa/drivers/dri/i965/brw_state_upload.c | 4 +- 4 files changed, 88 insertions(+), 45 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index af9fef5e22..cad711d18a 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -467,7 +467,8 @@ struct brw_context int validated_bo_count; } state; - struct brw_cache cache; + struct brw_cache cache; /** non-surface items */ + struct brw_cache surface_cache; /* surface items */ struct brw_cached_batch_item *cached_batch_items; struct { diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 81b0a45998..7ea2fc113c 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -135,8 +135,8 @@ dri_bo *brw_search_cache( struct brw_cache *cache, void *aux_return); void brw_state_cache_check_size( struct brw_context *brw ); -void brw_init_cache( struct brw_context *brw ); -void brw_destroy_cache( struct brw_context *brw ); +void brw_init_caches( struct brw_context *brw ); +void brw_destroy_caches( struct brw_context *brw ); /*********************************************************************** * brw_state_batch.c diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index d5b5166406..3b23a8b755 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -320,20 +320,20 @@ enum pool_type { }; static void -brw_init_cache_id( struct brw_context *brw, - const char *name, - enum brw_cache_id id, - GLuint key_size, - GLuint aux_size) +brw_init_cache_id(struct brw_cache *cache, + const char *name, + enum brw_cache_id id, + GLuint key_size, + GLuint aux_size) { - struct brw_cache *cache = &brw->cache; - cache->name[id] = strdup(name); cache->key_size[id] = key_size; cache->aux_size[id] = aux_size; } -void brw_init_cache( struct brw_context *brw ) + +static void +brw_init_non_surface_cache( struct brw_context *brw ) { struct brw_cache *cache = &brw->cache; @@ -342,114 +342,145 @@ void brw_init_cache( struct brw_context *brw ) cache->size = 7; cache->n_items = 0; cache->items = (struct brw_cache_item **) - _mesa_calloc(cache->size * - sizeof(struct brw_cache_item)); + _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "CC_VP", BRW_CC_VP, sizeof(struct brw_cc_viewport), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT, sizeof(struct brw_cc_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG, sizeof(struct brw_wm_prog_key), sizeof(struct brw_wm_prog_data)); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SAMPLER_DEFAULT_COLOR", BRW_SAMPLER_DEFAULT_COLOR, sizeof(struct brw_sampler_default_color), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER, 0, /* variable key/data size */ 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT, sizeof(struct brw_wm_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG, sizeof(struct brw_sf_prog_key), sizeof(struct brw_sf_prog_data)); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SF_VP", BRW_SF_VP, sizeof(struct brw_sf_viewport), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT, sizeof(struct brw_sf_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT, sizeof(struct brw_vs_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG, sizeof(struct brw_vs_prog_key), sizeof(struct brw_vs_prog_data)); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT, sizeof(struct brw_clip_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG, sizeof(struct brw_clip_prog_key), sizeof(struct brw_clip_prog_data)); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT, sizeof(struct brw_gs_unit_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG, sizeof(struct brw_gs_prog_key), sizeof(struct brw_gs_prog_data)); +#if 1 + brw_init_cache_id(cache, + "SS_SURFACE", + BRW_SS_SURFACE, + sizeof(struct brw_surface_state), + 0); + + brw_init_cache_id(cache, + "SS_SURF_BIND", + BRW_SS_SURF_BIND, + 0, + 0); +#endif +} + +static void +brw_init_surface_cache( struct brw_context *brw ) +{ + struct brw_cache *cache = &brw->surface_cache; - brw_init_cache_id(brw, + cache->brw = brw; + + cache->size = 7; + cache->n_items = 0; + cache->items = (struct brw_cache_item **) + _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); + + brw_init_cache_id(cache, "SS_SURFACE", BRW_SS_SURFACE, sizeof(struct brw_surface_state), 0); - brw_init_cache_id(brw, + brw_init_cache_id(cache, "SS_SURF_BIND", BRW_SS_SURF_BIND, 0, 0); } +void brw_init_caches( struct brw_context *brw ) +{ + brw_init_non_surface_cache(brw); + brw_init_surface_cache(brw); +} + static void -brw_clear_cache( struct brw_context *brw ) +brw_clear_cache( struct brw_context *brw, struct brw_cache *cache ) { struct brw_cache_item *c, *next; GLuint i; @@ -457,8 +488,8 @@ brw_clear_cache( struct brw_context *brw ) if (INTEL_DEBUG & DEBUG_STATE) _mesa_printf("%s\n", __FUNCTION__); - for (i = 0; i < brw->cache.size; i++) { - for (c = brw->cache.items[i]; c; c = next) { + for (i = 0; i < cache->size; i++) { + for (c = cache->items[i]; c; c = next) { int j; next = c->next; @@ -468,10 +499,10 @@ brw_clear_cache( struct brw_context *brw ) free((void *)c->key); free(c); } - brw->cache.items[i] = NULL; + cache->items[i] = NULL; } - brw->cache.n_items = 0; + cache->n_items = 0; if (brw->curbe.last_buf) { _mesa_free(brw->curbe.last_buf); @@ -489,19 +520,30 @@ void brw_state_cache_check_size( struct brw_context *brw ) * 32k, so 1000 of them is around 1.5MB. */ if (brw->cache.n_items > 1000) - brw_clear_cache(brw); + brw_clear_cache(brw, &brw->cache); + + if (brw->surface_cache.n_items > 1000) + brw_clear_cache(brw, &brw->surface_cache); } -void brw_destroy_cache( struct brw_context *brw ) + +static void +brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) { GLuint i; - brw_clear_cache(brw); + brw_clear_cache(brw, cache); for (i = 0; i < BRW_MAX_CACHE; i++) { - dri_bo_unreference(brw->cache.last_bo[i]); - free(brw->cache.name[i]); + dri_bo_unreference(cache->last_bo[i]); + free(cache->name[i]); } - free(brw->cache.items); - brw->cache.items = NULL; - brw->cache.size = 0; + free(cache->items); + cache->items = NULL; + cache->size = 0; +} + +void brw_destroy_caches( struct brw_context *brw ) +{ + brw_destroy_cache(brw, &brw->cache); + brw_destroy_cache(brw, &brw->surface_cache); } diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 20892cdf32..2641bcb2aa 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -100,13 +100,13 @@ const struct brw_tracked_state *atoms[] = void brw_init_state( struct brw_context *brw ) { - brw_init_cache(brw); + brw_init_caches(brw); } void brw_destroy_state( struct brw_context *brw ) { - brw_destroy_cache(brw); + brw_destroy_caches(brw); brw_destroy_batch_cache(brw); } -- cgit v1.2.3 From 4843e54fc69daf379dea9899673b3df92b44049c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:12:07 -0600 Subject: i965: actually use the new, second surface state cache --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 39 +++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 89c456e62c..74f3f1791e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -268,7 +268,7 @@ brw_create_texture_surface( struct brw_context *brw, surf.ss0.cube_neg_z = 1; } - bo = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, + bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, &surf, sizeof(surf), @@ -321,10 +321,11 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) key.tiling = intelObj->mt->region->tiling; dri_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, key.bo ? 1 : 0, - NULL); + brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL); if (brw->wm.surf_bo[surf] == NULL) { brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key); } @@ -362,7 +363,7 @@ brw_create_constant_surface( struct brw_context *brw, surf.ss3.pitch = (key->pitch * key->cpp) - 1; /* ignored?? */ brw_set_surface_tiling(&surf, key->tiling); /* tiling now allowed */ - bo = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, + bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, &surf, sizeof(surf), @@ -427,7 +428,8 @@ brw_update_wm_constant_surface( GLcontext *ctx, */ dri_bo_unreference(brw->wm.surf_bo[surf]); - brw->wm.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, &key, sizeof(key), &key.bo, key.bo ? 1 : 0, NULL); @@ -484,7 +486,8 @@ brw_update_vs_constant_surface( GLcontext *ctx, */ dri_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, &key, sizeof(key), &key.bo, key.bo ? 1 : 0, NULL); @@ -563,10 +566,11 @@ brw_update_renderbuffer_surface(struct brw_context *brw, dri_bo_unreference(brw->wm.surf_bo[unit]); brw->wm.surf_bo[unit] = NULL; if (cached) - brw->wm.surf_bo[unit] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, - &key, sizeof(key), - ®ion_bo, 1, - NULL); + brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + ®ion_bo, 1, + NULL); if (brw->wm.surf_bo[unit] == NULL) { struct brw_surface_state surf; @@ -591,7 +595,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw, surf.ss0.writedisable_alpha = !key.color_mask[3]; /* Key size will never match key size for textures, so we're safe. */ - brw->wm.surf_bo[unit] = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, + brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache, + BRW_SS_SURFACE, &key, sizeof(key), ®ion_bo, 1, &surf, sizeof(surf), @@ -623,7 +628,7 @@ brw_wm_get_binding_table(struct brw_context *brw) assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF); - bind_bo = brw_search_cache(&brw->cache, BRW_SS_SURF_BIND, + bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->wm.surf_bo, brw->wm.nr_surfaces, NULL); @@ -639,7 +644,7 @@ brw_wm_get_binding_table(struct brw_context *brw) else data[i] = 0; - bind_bo = brw_upload_cache( &brw->cache, BRW_SS_SURF_BIND, + bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->wm.surf_bo, brw->wm.nr_surfaces, data, data_size, @@ -739,7 +744,7 @@ brw_vs_get_binding_table(struct brw_context *brw) assert(brw->vs.nr_surfaces <= BRW_VS_MAX_SURF); - bind_bo = brw_search_cache(&brw->cache, BRW_SS_SURF_BIND, + bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->vs.surf_bo, brw->vs.nr_surfaces, NULL); @@ -755,7 +760,7 @@ brw_vs_get_binding_table(struct brw_context *brw) else data[i] = 0; - bind_bo = brw_upload_cache( &brw->cache, BRW_SS_SURF_BIND, + bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->vs.surf_bo, brw->vs.nr_surfaces, data, data_size, -- cgit v1.2.3 From fa92756400ccfbb3f0201df634feb45ab4f98352 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 18:16:03 +0100 Subject: mesa: Fix buffer overflow when parsing generic vertex attributes. --- src/mesa/shader/arbprogparse.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index b47bf360cf..c7a031067e 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1513,10 +1513,16 @@ generic_attrib_check(struct var_cache *vc_head) curr = vc_head; while (curr) { if (curr->type == vt_attrib) { - if (curr->attrib_is_generic) - genericAttrib[ curr->attrib_binding ] = GL_TRUE; - else + if (curr->attrib_is_generic) { + GLuint attr = (curr->attrib_binding == 0) + ? 0 : (curr->attrib_binding - VERT_ATTRIB_GENERIC0); + assert(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + genericAttrib[attr] = GL_TRUE; + } + else { + assert(curr->attrib_binding < MAX_VERTEX_PROGRAM_ATTRIBS); explicitAttrib[ curr->attrib_binding ] = GL_TRUE; + } } curr = curr->next; -- cgit v1.2.3 From c0c58cf5cfc11b9256287871660cc16966e662ef Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:28:24 -0600 Subject: i965: comments, reformatting --- src/mesa/drivers/dri/i965/brw_state_cache.c | 55 ++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 17 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 3b23a8b755..cbae68798c 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -56,9 +56,9 @@ * incorrect program is run for the other instance. */ +#include "main/imports.h" #include "brw_state.h" #include "intel_batchbuffer.h" -#include "main/imports.h" /* XXX: Fixme - have to include these to get the sizes of the prog_key * structs: @@ -69,8 +69,10 @@ #include "brw_sf.h" #include "brw_gs.h" -static GLuint hash_key( const void *key, GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs) + +static GLuint +hash_key(const void *key, GLuint key_size, + dri_bo **reloc_bufs, GLuint nr_reloc_bufs) { GLuint *ikey = (GLuint *)key; GLuint hash = 0, i; @@ -95,6 +97,7 @@ static GLuint hash_key( const void *key, GLuint key_size, return hash; } + /** * Marks a new buffer as being chosen for the given cache id. */ @@ -111,6 +114,7 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, cache->brw->state.dirty.cache |= 1 << cache_id; } + static struct brw_cache_item * search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, GLuint hash, const void *key, GLuint key_size, @@ -143,7 +147,8 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, } -static void rehash( struct brw_cache *cache ) +static void +rehash(struct brw_cache *cache) { struct brw_cache_item **items; struct brw_cache_item *c, *next; @@ -164,15 +169,17 @@ static void rehash( struct brw_cache *cache ) cache->size = size; } + /** * Returns the buffer object matching cache_id and key, or NULL. */ -dri_bo *brw_search_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs, - void *aux_return ) +dri_bo * +brw_search_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + dri_bo **reloc_bufs, GLuint nr_reloc_bufs, + void *aux_return) { struct brw_cache_item *item; GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); @@ -192,6 +199,7 @@ dri_bo *brw_search_cache( struct brw_cache *cache, return item->bo; } + dri_bo * brw_upload_cache( struct brw_cache *cache, enum brw_cache_id cache_id, @@ -265,7 +273,9 @@ brw_upload_cache( struct brw_cache *cache, return bo; } -/* This doesn't really work with aux data. Use search/upload instead + +/** + * This doesn't really work with aux data. Use search/upload instead */ dri_bo * brw_cache_data_sz(struct brw_cache *cache, @@ -296,6 +306,7 @@ brw_cache_data_sz(struct brw_cache *cache, return bo; } + /** * Wrapper around brw_cache_data_sz using the cache_id's canonical key size. * @@ -319,6 +330,7 @@ enum pool_type { DW_GENERAL_STATE }; + static void brw_init_cache_id(struct brw_cache *cache, const char *name, @@ -333,7 +345,7 @@ brw_init_cache_id(struct brw_cache *cache, static void -brw_init_non_surface_cache( struct brw_context *brw ) +brw_init_non_surface_cache(struct brw_context *brw) { struct brw_cache *cache = &brw->cache; @@ -433,6 +445,7 @@ brw_init_non_surface_cache( struct brw_context *brw ) BRW_GS_PROG, sizeof(struct brw_gs_prog_key), sizeof(struct brw_gs_prog_data)); + #if 1 brw_init_cache_id(cache, "SS_SURFACE", @@ -448,8 +461,9 @@ brw_init_non_surface_cache( struct brw_context *brw ) #endif } + static void -brw_init_surface_cache( struct brw_context *brw ) +brw_init_surface_cache(struct brw_context *brw) { struct brw_cache *cache = &brw->surface_cache; @@ -473,14 +487,17 @@ brw_init_surface_cache( struct brw_context *brw ) 0); } -void brw_init_caches( struct brw_context *brw ) + +void +brw_init_caches(struct brw_context *brw) { brw_init_non_surface_cache(brw); brw_init_surface_cache(brw); } + static void -brw_clear_cache( struct brw_context *brw, struct brw_cache *cache ) +brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) { struct brw_cache_item *c, *next; GLuint i; @@ -514,7 +531,9 @@ brw_clear_cache( struct brw_context *brw, struct brw_cache *cache ) brw->state.dirty.cache |= ~0; } -void brw_state_cache_check_size( struct brw_context *brw ) + +void +brw_state_cache_check_size(struct brw_context *brw) { /* un-tuned guess. We've got around 20 state objects for a total of around * 32k, so 1000 of them is around 1.5MB. @@ -542,7 +561,9 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) cache->size = 0; } -void brw_destroy_caches( struct brw_context *brw ) + +void +brw_destroy_caches(struct brw_context *brw) { brw_destroy_cache(brw, &brw->cache); brw_destroy_cache(brw, &brw->surface_cache); -- cgit v1.2.3 From 21a422d97e501f4ca68ab24ad3fe5f5eb1393349 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:29:49 -0600 Subject: i965: remove old code to init surface-related cache IDs These types are only found in the new surface state cache now. --- src/mesa/drivers/dri/i965/brw_state_cache.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index cbae68798c..320d886c99 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -445,20 +445,6 @@ brw_init_non_surface_cache(struct brw_context *brw) BRW_GS_PROG, sizeof(struct brw_gs_prog_key), sizeof(struct brw_gs_prog_data)); - -#if 1 - brw_init_cache_id(cache, - "SS_SURFACE", - BRW_SS_SURFACE, - sizeof(struct brw_surface_state), - 0); - - brw_init_cache_id(cache, - "SS_SURF_BIND", - BRW_SS_SURF_BIND, - 0, - 0); -#endif } -- cgit v1.2.3 From 5c8fb6acc10662c9e71078c9f273db6c7808e9ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:47:59 -0600 Subject: i965: define BRW_MAX_GRF --- src/mesa/drivers/dri/i965/brw_context.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index cad711d18a..f0d4993e11 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -243,6 +243,9 @@ struct brw_vs_ouput_sizes { }; +/** Number of general purpose registers (VS, WM, etc) */ +#define BRW_MAX_GRF 128 + /** Number of texture sampler units */ #define BRW_MAX_TEX_UNIT 16 -- cgit v1.2.3 From ac22178eb049126003db40b0a77a111498a12ab7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 11:52:16 -0600 Subject: i965: enable VS constant buffers In the VS constants can now be handled in two different ways: 1. If there's room in the GRF, put constants there. They're preloaded from the CURBE prior to VS execution. This is the historical approach. The problem is the GRF may not have room for all the shader's constants and temps and misc registers. Hence... 2. Use a separate constant buffer which is read from using a READ message. This allows a very large number of constants and frees up GRF regs for shader temporaries. This is the new approach. May be a little slower than 1. 1 vs. 2 is chosen according to how many constants and temps the shader needs. --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 524f1211ce..1da5a3f502 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -69,13 +69,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) { GLuint i, reg = 0, mrf; -#if 0 - if (c->vp->program.Base.Parameters->NumParameters >= 6) - c->use_const_buffer = 1; + /* Determine whether to use a real constant buffer or use a block + * of GRF registers for constants. The later is faster but only + * works if everything fits in the GRF. + * XXX this heuristic/check may need some fine tuning... + */ + if (c->vp->program.Base.Parameters->NumParameters + + c->vp->program.Base.NumTemporaries + 20 > BRW_MAX_GRF) + c->use_const_buffer = GL_TRUE; else -#endif c->use_const_buffer = GL_FALSE; - /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/ + printf("use_const_buffer = %d\n", c->use_const_buffer); /* r0 -- reserved as usual */ -- cgit v1.2.3 From ebfbd8c4fef78e3cd9604660e5bb96e3c6df07e5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 13:46:58 -0600 Subject: i965: disable debug printf --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 1da5a3f502..c2b3702798 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -79,7 +79,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) c->use_const_buffer = GL_TRUE; else c->use_const_buffer = GL_FALSE; - printf("use_const_buffer = %d\n", c->use_const_buffer); + /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/ /* r0 -- reserved as usual */ -- cgit v1.2.3 From 8ee6ab6acb8f89fbc87865751573fcbffb4695ef Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 15:02:01 -0600 Subject: mesa: fix _mesa_dump_textures(), add null ptr check Calling _mesa_dump_textures() deleted the textures... oops!!! --- src/mesa/main/debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index fdd10dd307..2eabcdaf49 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -3,6 +3,7 @@ * Version: 6.5 * * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -262,7 +263,7 @@ static void write_texture_image(struct gl_texture_object *texObj) { const struct gl_texture_image *img = texObj->Image[0][0]; - if (img) { + if (img && img->Data) { char s[100]; /* make filename */ @@ -338,5 +339,5 @@ _mesa_dump_textures(GLboolean dumpImages) { GET_CURRENT_CONTEXT(ctx); DumpImages = dumpImages; - _mesa_HashDeleteAll(ctx->Shared->TexObjects, dump_texture_cb, ctx); + _mesa_HashWalk(ctx->Shared->TexObjects, dump_texture_cb, ctx); } -- cgit v1.2.3 From 984f2bb629bb742c6d11d4c8434a2cb32a5b8b75 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 15:10:36 -0600 Subject: st: comments, license, copyright --- src/mesa/state_tracker/st_inlines.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h index 0322d5dfa6..a41cfeb96f 100644 --- a/src/mesa/state_tracker/st_inlines.h +++ b/src/mesa/state_tracker/st_inlines.h @@ -1,3 +1,35 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Functions for checking if buffers/textures are referenced when we need + * to read/write from/to them. Flush when needed. + */ + #ifndef ST_INLINES_H #define ST_INLINES_H -- cgit v1.2.3 From 725d50601c2c010ce427a23a6e023f79df8a3a22 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 16:38:04 -0600 Subject: mesa: fix comment typo --- src/mesa/main/pixel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 52781e048e..57ae9c721a 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -819,7 +819,7 @@ update_image_transfer_state(GLcontext *ctx) /** - * Update meas pixel transfer derived state. + * Update mesa pixel transfer derived state. */ void _mesa_update_pixel( GLcontext *ctx, GLuint new_state ) { -- cgit v1.2.3 From 6b0c9366a3f13d74c00666cb7c26b65732f6b1aa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 16:41:05 -0600 Subject: mesa: minor state-update changes in histogram code Call FLUSH_VERTICES() in _mesa_Histogram(). No need to signal _NEW_PIXEL in ResetHistogram(), ResetMinmax(). --- src/mesa/main/histogram.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c index 905c1ad830..5fee4fd0e3 100644 --- a/src/mesa/main/histogram.c +++ b/src/mesa/main/histogram.c @@ -975,6 +975,8 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s } } + FLUSH_VERTICES(ctx, _NEW_PIXEL); + /* reset histograms */ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { ctx->Histogram.Count[i][0] = 0; @@ -1002,8 +1004,6 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s ctx->Histogram.AlphaSize = 8 * sizeof(GLuint); ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint); } - - ctx->NewState |= _NEW_PIXEL; } @@ -1058,8 +1058,6 @@ _mesa_ResetHistogram(GLenum target) ctx->Histogram.Count[i][2] = 0; ctx->Histogram.Count[i][3] = 0; } - - ctx->NewState |= _NEW_PIXEL; } @@ -1083,7 +1081,6 @@ _mesa_ResetMinmax(GLenum target) ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; - ctx->NewState |= _NEW_PIXEL; } -- cgit v1.2.3 From 4f4907d69f9020ce17aef21b6431d2dd65e01982 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 22 Apr 2009 16:24:42 -0700 Subject: intel: Take advantage of GL_READ_ONLY_ARB to map to GEM bo_map write flag. This is a CPU win in general, but in particular reduces the pain of Mesa's calculation of min/max indices in DrawElements (wtf?). --- src/mesa/drivers/dri/i965/brw_curbe.c | 4 ++-- src/mesa/drivers/dri/intel/intel_buffer_objects.c | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 18b187ed1d..03371564e1 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -353,10 +353,10 @@ update_constant_buffer(struct brw_context *brw, assert(const_buffer); assert(const_buffer->size >= size); - dri_bo_map(const_buffer, GL_TRUE); + drm_intel_gem_bo_map_gtt(const_buffer); map = const_buffer->virtual; memcpy(map, params->ParameterValues, size); - dri_bo_unmap(const_buffer); + drm_intel_gem_bo_unmap_gtt(const_buffer); if (0) { int i; diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index b7c7eeb368..c849e4869e 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -204,9 +204,8 @@ intel_bufferobj_map(GLcontext * ctx, { struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + GLboolean read_only = (access == GL_READ_ONLY_ARB); - /* XXX: Translate access to flags arg below: - */ assert(intel_obj); if (intel_obj->region) @@ -217,7 +216,7 @@ intel_bufferobj_map(GLcontext * ctx, return NULL; } - dri_bo_map(intel_obj->buffer, GL_TRUE); + dri_bo_map(intel_obj->buffer, !read_only); obj->Pointer = intel_obj->buffer->virtual; return obj->Pointer; } -- cgit v1.2.3 From 8374379572d1c541a804990bc926108360f67c02 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 23 Apr 2009 09:37:55 -0700 Subject: i965: Support drawing to FBO cube faces other than positive X. Also fixes drawing to 3D texture depth levels. --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 71840d1e4e..805df8a4af 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -520,6 +520,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, GLubyte color_mask[4]; GLboolean color_blend; uint32_t tiling; + uint32_t draw_offset; } key; memset(&key, 0, sizeof(key)); @@ -550,6 +551,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.height = region->height; key.pitch = region->pitch; key.cpp = region->cpp; + key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */ } else { key.surface_type = BRW_SURFACE_NULL; key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; @@ -557,6 +559,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.width = 1; key.height = 1; key.cpp = 4; + key.draw_offset = 0; } memcpy(key.color_mask, ctx->Color.ColorMask, sizeof(key.color_mask)); @@ -578,8 +581,9 @@ brw_update_renderbuffer_surface(struct brw_context *brw, surf.ss0.surface_format = key.surface_format; surf.ss0.surface_type = key.surface_type; + surf.ss1.base_addr = key.draw_offset; if (region_bo != NULL) - surf.ss1.base_addr = region_bo->offset; /* reloc */ + surf.ss1.base_addr += region_bo->offset; /* reloc */ surf.ss2.width = key.width - 1; surf.ss2.height = key.height - 1; @@ -604,12 +608,12 @@ brw_update_renderbuffer_surface(struct brw_context *brw, * them both. We might be able to figure out from other state * a more restrictive relocation to emit. */ - dri_bo_emit_reloc(brw->wm.surf_bo[unit], - I915_GEM_DOMAIN_RENDER, - I915_GEM_DOMAIN_RENDER, - 0, - offsetof(struct brw_surface_state, ss1), - region_bo); + drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit], + offsetof(struct brw_surface_state, ss1), + region_bo, + key.draw_offset, + I915_GEM_DOMAIN_RENDER, + I915_GEM_DOMAIN_RENDER); } } } -- cgit v1.2.3 From ae69a046505d8c94cd3a59a9376310a904c35b3c Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 23 Apr 2009 21:55:25 +0200 Subject: i915: fix fix for anisotropic filtering forgot to commit the changes to actually support 4x aniso filtering... --- src/mesa/drivers/dri/i915/i915_texstate.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 43f65392b5..a37dd7f4fb 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -132,7 +132,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_texture_image *firstImage; GLuint *state = i915->state.Tex[unit], format, pitch; - GLint lodbias; + GLint lodbias, aniso = 0; GLubyte border[4]; memset(state, 0, sizeof(state)); @@ -230,6 +230,10 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) if (tObj->MaxAnisotropy > 1.0) { minFilt = FILTER_ANISOTROPIC; magFilt = FILTER_ANISOTROPIC; + if (tObj->MaxAnisotropy > 2.0) + aniso = SS2_MAX_ANISO_4; + else + aniso = SS2_MAX_ANISO_2; } else { switch (tObj->MagFilter) { @@ -275,7 +279,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT)); + (magFilt << SS2_MAG_FILTER_SHIFT) | + aniso); } { -- cgit v1.2.3 From a9a363f8298e9d534e60e3d2869f8677138a1e7e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Apr 2009 17:41:23 -0600 Subject: i965: revert part of commit 4f4907d69f9020ce17aef21b6431d2dd65e01982 The drm_intel_gem_bo_map_gtt() call that replaced dri_bo_map() is producing errors like: intel_bufmgr_gem.c:689: Error preparing buffer map 39 (vp_const_buffer): Invalid argument . and returning NULL, causing a segfault in the memcpy(). Just reverting until we can get to the root issue... --- src/mesa/drivers/dri/i965/brw_curbe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 03371564e1..18b187ed1d 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -353,10 +353,10 @@ update_constant_buffer(struct brw_context *brw, assert(const_buffer); assert(const_buffer->size >= size); - drm_intel_gem_bo_map_gtt(const_buffer); + dri_bo_map(const_buffer, GL_TRUE); map = const_buffer->virtual; memcpy(map, params->ParameterValues, size); - drm_intel_gem_bo_unmap_gtt(const_buffer); + dri_bo_unmap(const_buffer); if (0) { int i; -- cgit v1.2.3 From 1d0039959302fddd560dc7f9642f312e588cce0e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Apr 2009 17:54:34 -0600 Subject: mesa: more informative error messages --- src/mesa/main/texparam.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 515a35cdfc..e60ab6aa12 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -69,7 +69,7 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap) return GL_TRUE; } - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap ); return GL_FALSE; } @@ -209,7 +209,8 @@ set_tex_parameteri(GLcontext *ctx, } /* fall-through */ default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0] ); } return GL_FALSE; @@ -223,7 +224,8 @@ set_tex_parameteri(GLcontext *ctx, texObj->MagFilter = params[0]; return GL_TRUE; default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0]); } return GL_FALSE; @@ -262,7 +264,8 @@ set_tex_parameteri(GLcontext *ctx, return GL_FALSE; if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_VALUE, + "glTexParameter(param=%d)", params[0]); return GL_FALSE; } flush(ctx, texObj); @@ -273,7 +276,8 @@ set_tex_parameteri(GLcontext *ctx, if (texObj->MaxLevel == params[0]) return GL_FALSE; if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexParameter(param=%d)", params[0]); return GL_FALSE; } flush(ctx, texObj); @@ -340,7 +344,7 @@ set_tex_parameteri(GLcontext *ctx, } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } return GL_FALSE; -- cgit v1.2.3 From ff71587b27beaf288d535e14c75e58425d7efc7a Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 23 Apr 2009 23:41:41 +0200 Subject: i965: fix point size issue need to clamp point size to user set min/max values, even for constant point size. Fixes glean pointAtten test. --- src/mesa/drivers/dri/i965/brw_sf_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index fc4eddda0a..68fa9820b6 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -147,7 +147,7 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key) key->line_smooth = ctx->Line.SmoothFlag; key->point_sprite = ctx->Point.PointSprite; - key->point_size = ctx->Point.Size; + key->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); key->point_attenuated = ctx->Point._Attenuated; key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0; -- cgit v1.2.3 From 027ed1b505a1bf6e3f5ad4412734d7edf337c08b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 09:43:44 -0600 Subject: mesa: signal _NEW_PROGRAM_CONSTANTS instead of _NEW_PROGRAM Use _NEW_PROGRAM_CONSTANTS when changing constant/uniform buffer values. Binding a new program/shader sets both _NEW_PROGRAM and _NEW_PROGRAM_CONSTANTS. --- src/mesa/shader/arbprogram.c | 13 +++++++------ src/mesa/shader/nvprogram.c | 2 +- src/mesa/shader/shader_api.c | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index 981565ab8f..317d623a22 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -74,8 +74,6 @@ _mesa_BindProgram(GLenum target, GLuint id) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* Error-check target and get curProg */ if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */ (ctx->Extensions.NV_vertex_program || @@ -132,6 +130,9 @@ _mesa_BindProgram(GLenum target, GLuint id) return; } + /* signal new program (and its new constants) */ + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, @@ -489,7 +490,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { @@ -537,7 +538,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat * dest; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (count <= 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)"); @@ -631,7 +632,7 @@ _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, struct gl_program *prog; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if ((target == GL_FRAGMENT_PROGRAM_NV && ctx->Extensions.NV_fragment_program) || @@ -685,7 +686,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLint i; ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); if (count <= 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 5142c2a4a5..8ba521182b 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -706,7 +706,7 @@ _mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); prog = _mesa_lookup_program(ctx, id); if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) { diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 644cd39185..8f414a0889 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1487,7 +1487,7 @@ _mesa_use_program(GLcontext *ctx, GLuint program) return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); if (program) { shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); @@ -1789,7 +1789,7 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); uniform = &shProg->Uniforms->Uniforms[location]; @@ -1929,7 +1929,7 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, return; } - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); uniform = &shProg->Uniforms->Uniforms[location]; -- cgit v1.2.3 From 3321b6984ecd96ba466d8d010e390fff71a799d7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 09:50:11 -0600 Subject: i965: use drm_intel_gem_bo_map/unmap_gtt() when possible, otherwise dri_bo_subdata() This wraps up the unfinished business from commit a9a363f8298e9d534e60e3d2869f8677138a1e7e --- src/mesa/drivers/dri/i965/brw_curbe.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 18b187ed1d..2d15793078 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -344,19 +344,23 @@ update_constant_buffer(struct brw_context *brw, const struct gl_program_parameter_list *params, dri_bo *const_buffer) { + struct intel_context *intel = &brw->intel; const int size = params->NumParameters * 4 * sizeof(GLfloat); /* copy Mesa program constants into the buffer */ if (const_buffer && size > 0) { - GLubyte *map; assert(const_buffer); assert(const_buffer->size >= size); - dri_bo_map(const_buffer, GL_TRUE); - map = const_buffer->virtual; - memcpy(map, params->ParameterValues, size); - dri_bo_unmap(const_buffer); + if (intel->intelScreen->kernel_exec_fencing) { + drm_intel_gem_bo_map_gtt(const_buffer); + memcpy(const_buffer->virtual, params->ParameterValues, size); + drm_intel_gem_bo_unmap_gtt(const_buffer); + } + else { + dri_bo_subdata(const_buffer, 0, size, params->ParameterValues); + } if (0) { int i; -- cgit v1.2.3 From 1c9786894cc3ce66665ca507a6daf6a829e5af89 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 10:46:40 -0600 Subject: mesa: fix up error/warning/debug output newlines As of commit 23ad86cfb91c294ce85a3116d4b825aaa3988a6e all messages go through output_if_debug(). Add new parameter to output_if_debug() to indicate whether to emit a newline. _mesa_warning() and _mesa_error() calls should not end their strings with \n. _mesa_debug() calls should end their text with \n. --- src/mesa/main/context.c | 2 +- src/mesa/main/imports.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 5726dbd983..4469c8e1fa 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -434,7 +434,7 @@ one_time_init( GLcontext *ctx ) } #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) - _mesa_debug(ctx, "Mesa %s DEBUG build %s %s", + _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", MESA_VERSION_STRING, __DATE__, __TIME__); #endif diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 2ac93a5237..8797f36695 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -980,7 +980,8 @@ _mesa_vsprintf( char *str, const char *fmt, va_list args ) /*@{*/ static void -output_if_debug(const char *prefixString, const char *outputString) +output_if_debug(const char *prefixString, const char *outputString, + GLboolean newline) { static int debug = -1; @@ -1004,16 +1005,19 @@ output_if_debug(const char *prefixString, const char *outputString) /* Now only print the string if we're required to do so. */ if (debug) { - fprintf(stderr, "%s: %s\n", prefixString, outputString); + fprintf(stderr, "%s: %s", prefixString, outputString); + if (newline) + fprintf(stderr, "\n"); } } + /** * Report a warning (a recoverable error condition) to stderr if * either DEBUG is defined or the MESA_DEBUG env var is set. * * \param ctx GL context. - * \param fmtString printf() alike format string. + * \param fmtString printf()-like format string. */ void _mesa_warning( GLcontext *ctx, const char *fmtString, ... ) @@ -1025,11 +1029,12 @@ _mesa_warning( GLcontext *ctx, const char *fmtString, ... ) (void) vsnprintf( str, MAXSTRING, fmtString, args ); va_end( args ); - output_if_debug("Mesa warning", str); + output_if_debug("Mesa warning", str, GL_TRUE); } + /** - * Report an internla implementation problem. + * Report an internal implementation problem. * Prints the message to stderr via fprintf(). * * \param ctx GL context. @@ -1050,8 +1055,9 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) fprintf(stderr, "Please report at bugzilla.freedesktop.org\n"); } + /** - * Record an OpenGL state error. These usually occur when the users + * Record an OpenGL state error. These usually occur when the user * passes invalid parameters to a GL function. * * If debugging is enabled (either at compile-time via the DEBUG macro, or @@ -1123,11 +1129,22 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) errstr = "unknown"; break; } - _mesa_debug(ctx, "User error: %s in %s\n", errstr, where); + + { + char s[MAXSTRING], s2[MAXSTRING]; + va_list args; + va_start(args, fmtString); + vsnprintf(s, MAXSTRING, fmtString, args); + va_end(args); + + snprintf(s2, MAXSTRING, "%s in %s", errstr, s); + output_if_debug("Mesa: User error", s2, GL_TRUE); + } } _mesa_record_error(ctx, error); -} +} + /** * Report debug information. Print error message to stderr via fprintf(). @@ -1145,7 +1162,7 @@ _mesa_debug( const GLcontext *ctx, const char *fmtString, ... ) va_start(args, fmtString); vsnprintf(s, MAXSTRING, fmtString, args); va_end(args); - output_if_debug("Mesa", s); + output_if_debug("Mesa", s, GL_FALSE); #endif /* DEBUG */ (void) ctx; (void) fmtString; -- cgit v1.2.3 From f2272b5b2fd9195fe8f9eccfdd2e3c13d18a35e7 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 20 Apr 2009 20:56:45 -0700 Subject: intel / DRI2: When available, use DRI2GetBuffersWithFormat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This interface gives the driver two important features. First, it can allocate the (fake) front-buffer only when needed. Second, it can tell the buffer allocator the format of buffers being allocated. This enables support for back-buffer and depth-buffer with different bits per pixel. Signed-off-by: Ian Romanick Reviewed-by: Kristian Høgsberg --- src/mesa/drivers/dri/intel/intel_buffers.c | 10 +++ src/mesa/drivers/dri/intel/intel_context.c | 105 ++++++++++++++++++++++++----- 2 files changed, 99 insertions(+), 16 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 90964df355..ecac5bf020 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -323,8 +323,18 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) { if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) { struct intel_context *const intel = intel_context(ctx); + const GLboolean was_front_buffer_rendering = + intel->is_front_buffer_rendering; intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT); + + /* If we weren't front-buffer rendering before but we are now, make sure + * that the front-buffer has actually been allocated. + */ + if (!was_front_buffer_rendering && intel->is_front_buffer_rendering) { + intel_update_renderbuffers(intel->driContext, + intel->driContext->driDrawablePriv); + } } intel_draw_buffer(ctx, ctx->DrawBuffer); diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 9b628dbc8e..7fda793373 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -173,6 +173,24 @@ intelGetString(GLcontext * ctx, GLenum name) } } +static unsigned +intel_bits_per_pixel(const struct intel_renderbuffer *rb) +{ + switch (rb->Base._ActualFormat) { + case GL_RGB5: + case GL_DEPTH_COMPONENT16: + return 16; + case GL_RGB8: + case GL_RGBA8: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH24_STENCIL8_EXT: + case GL_STENCIL_INDEX8_EXT: + return 32; + default: + return 0; + } +} + void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) { @@ -192,22 +210,62 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = intel->intelScreen->driScrnPriv; - i = 0; - if (intel_fb->color_rb[0]) - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (intel_fb->color_rb[1]) - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) - attachments[i++] = __DRI_BUFFER_DEPTH; - if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) - attachments[i++] = __DRI_BUFFER_STENCIL; - - buffers = (*screen->dri2.loader->getBuffers)(drawable, - &drawable->w, - &drawable->h, - attachments, i, - &count, - drawable->loaderPrivate); + if ((screen->dri2.loader->base.version > 2) + && (screen->dri2.loader->getBuffersWithFormat != NULL)) { + struct intel_renderbuffer *depth_rb; + struct intel_renderbuffer *stencil_rb; + + i = 0; + if ((intel->is_front_buffer_rendering || !intel_fb->color_rb[1]) + && intel_fb->color_rb[0]) { + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]); + } + + if (intel_fb->color_rb[1]) { + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + if ((depth_rb != NULL) && (stencil_rb != NULL)) { + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (depth_rb != NULL) { + attachments[i++] = __DRI_BUFFER_DEPTH; + attachments[i++] = intel_bits_per_pixel(depth_rb); + } else if (stencil_rb != NULL) { + attachments[i++] = __DRI_BUFFER_STENCIL; + attachments[i++] = intel_bits_per_pixel(stencil_rb); + } + + buffers = + (*screen->dri2.loader->getBuffersWithFormat)(drawable, + &drawable->w, + &drawable->h, + attachments, i / 2, + &count, + drawable->loaderPrivate); + } else { + i = 0; + if (intel_fb->color_rb[0]) + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (intel_fb->color_rb[1]) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH)) + attachments[i++] = __DRI_BUFFER_DEPTH; + if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL)) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, + &drawable->h, + attachments, i, + &count, + drawable->loaderPrivate); + } if (buffers == NULL) return; @@ -250,6 +308,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) region_name = "dri2 depth buffer"; break; + case __DRI_BUFFER_DEPTH_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + region_name = "dri2 depth / stencil buffer"; + break; + case __DRI_BUFFER_STENCIL: rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); region_name = "dri2 stencil buffer"; @@ -296,6 +359,16 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_renderbuffer_set_region(rb, region); intel_region_release(®ion); + + if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { + struct intel_region *stencil_region; + + intel_region_reference(&stencil_region, region); + + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + intel_renderbuffer_set_region(rb, stencil_region); + intel_region_release(&stencil_region); + } } driUpdateFramebufferSize(&intel->ctx, drawable); -- cgit v1.2.3 From 302ba83116a24dbcd09a5f8d10edaaf862127873 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 24 Apr 2009 16:14:51 -0700 Subject: intel: Initialize region ptr to prevent assertion in intel_region_reference --- src/mesa/drivers/dri/intel/intel_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 7fda793373..8446032742 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -361,7 +361,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_region_release(®ion); if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { - struct intel_region *stencil_region; + struct intel_region *stencil_region = NULL; intel_region_reference(&stencil_region, region); -- cgit v1.2.3 From 022319b92ccd2f3bfc4aca54ebc7e39aeddd8b21 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 24 Apr 2009 16:39:00 -0700 Subject: intel: Fix more issues with the combined depth-stencil attachment --- src/mesa/drivers/dri/intel/intel_context.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 8446032742..eb224a8a41 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -361,13 +361,20 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) intel_region_release(®ion); if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { - struct intel_region *stencil_region = NULL; - - intel_region_reference(&stencil_region, region); - rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - intel_renderbuffer_set_region(rb, stencil_region); - intel_region_release(&stencil_region); + if (rb != NULL) { + struct intel_region *stencil_region = NULL; + + if (rb->region) { + dri_bo_flink(rb->region->buffer, &name); + if (name == buffers[i].name) + continue; + } + + intel_region_reference(&stencil_region, region); + intel_renderbuffer_set_region(rb, stencil_region); + intel_region_release(&stencil_region); + } } } -- cgit v1.2.3 From 4486e40143d16b7a6d28b4c652e671a198603131 Mon Sep 17 00:00:00 2001 From: Maciej Cencora Date: Tue, 21 Apr 2009 02:38:08 +0200 Subject: r300: always emit output insts after all KIL insts --- src/mesa/drivers/dri/r300/r300_state.c | 4 ++- src/mesa/drivers/dri/r300/radeon_program_pair.c | 45 +++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 8095538ff9..6b79aa4313 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -472,7 +472,9 @@ static void r300SetEarlyZState(GLcontext * ctx) if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) topZ = R300_ZTOP_DISABLE; - if (current_fragment_program_writes_depth(ctx)) + else if (current_fragment_program_writes_depth(ctx)) + topZ = R300_ZTOP_DISABLE; + else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill) topZ = R300_ZTOP_DISABLE; if (topZ != r300->hw.zstencil_format.cmd[2]) { diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/radeon_program_pair.c index 4aa2319a45..2e21f7bf66 100644 --- a/src/mesa/drivers/dri/r300/radeon_program_pair.c +++ b/src/mesa/drivers/dri/r300/radeon_program_pair.c @@ -47,6 +47,7 @@ struct pair_state_instruction { GLuint IsTex:1; /**< Is a texture instruction */ + GLuint IsOutput:1; /**< Is output instruction */ GLuint NeedRGB:1; /**< Needs the RGB ALU */ GLuint NeedAlpha:1; /**< Needs the Alpha ALU */ GLuint IsTranscendent:1; /**< Is a special transcendent instruction */ @@ -123,6 +124,7 @@ struct pair_state { GLboolean Debug; GLboolean Verbose; void *UserData; + GLubyte NumKillInsts; /** * Translate Mesa registers to hardware registers @@ -148,6 +150,11 @@ struct pair_state { struct pair_state_instruction *ReadyAlpha; struct pair_state_instruction *ReadyTEX; + /** + * Linked list of deferred instructions + */ + struct pair_state_instruction *DeferredInsts; + /** * Pool of @ref reg_value structures for fast allocation. */ @@ -231,7 +238,9 @@ static void instruction_ready(struct pair_state *s, int ip) if (s->Verbose) _mesa_printf("instruction_ready(%i)\n", ip); - if (pairinst->IsTex) + if (s->NumKillInsts > 0 && pairinst->IsOutput) + add_pairinst_to_list(&s->DeferredInsts, pairinst); + else if (pairinst->IsTex) add_pairinst_to_list(&s->ReadyTEX, pairinst); else if (!pairinst->NeedAlpha) add_pairinst_to_list(&s->ReadyRGB, pairinst); @@ -339,6 +348,8 @@ static void classify_instruction(struct pair_state *s, error("Unknown opcode %d\n", inst->Opcode); break; } + + pairinst->IsOutput = (inst->DstReg.File == PROGRAM_OUTPUT); } @@ -602,8 +613,11 @@ static void emit_all_tex(struct pair_state *s) struct prog_instruction *inst = s->Program->Instructions + ip; commit_instruction(s, ip); - if (inst->Opcode != OPCODE_KIL) + if (inst->Opcode == OPCODE_KIL) + --s->NumKillInsts; + else inst->DstReg.Index = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index); + inst->SrcReg[0].Index = get_hw_reg(s, inst->SrcReg[0].File, inst->SrcReg[0].Index); if (s->Debug) { @@ -861,6 +875,17 @@ static void emit_alu(struct pair_state *s) s->Error = s->Error || !s->Handler->EmitPaired(s->UserData, &pair); } +static GLubyte countKillInsts(struct gl_program *prog) +{ + GLubyte i, count = 0; + + for (i = 0; i < prog->NumInstructions; ++i) { + if (prog->Instructions[i].Opcode == OPCODE_KIL) + ++count; + } + + return count; +} GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, const struct radeon_pair_handler* handler, void *userdata) @@ -874,6 +899,7 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, s.UserData = userdata; s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE; s.Verbose = GL_FALSE && s.Debug; + s.NumKillInsts = countKillInsts(program); s.Instructions = (struct pair_state_instruction*)_mesa_calloc( sizeof(struct pair_state_instruction)*s.Program->NumInstructions); @@ -892,6 +918,21 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, if (s.ReadyTEX) emit_all_tex(&s); + if (!s.NumKillInsts) { + struct pair_state_instruction *pairinst = s.DeferredInsts; + while (pairinst) { + if (!pairinst->NeedAlpha) + add_pairinst_to_list(&s.ReadyRGB, pairinst); + else if (!pairinst->NeedRGB) + add_pairinst_to_list(&s.ReadyAlpha, pairinst); + else + add_pairinst_to_list(&s.ReadyFullALU, pairinst); + + pairinst = pairinst->NextReady; + } + s.DeferredInsts = NULL; + } + while(s.ReadyFullALU || s.ReadyRGB || s.ReadyAlpha) emit_alu(&s); } -- cgit v1.2.3 From 99b77d05d2e8c4af5f7d752d6827c21fd6c4d5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 27 Apr 2009 13:09:58 +0100 Subject: mesa: Call _mesa_snprintf instead of snprintf. snprintf not directly available on Windows. --- src/mesa/main/imports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 8797f36695..615f7c9a6d 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -1137,7 +1137,7 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) vsnprintf(s, MAXSTRING, fmtString, args); va_end(args); - snprintf(s2, MAXSTRING, "%s in %s", errstr, s); + _mesa_snprintf(s2, MAXSTRING, "%s in %s", errstr, s); output_if_debug("Mesa: User error", s2, GL_TRUE); } } -- cgit v1.2.3 From 7da3f9403b235394a5c7e9456e34a0c9dad7dd15 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 16:28:36 -0600 Subject: mesa: refactor code and make _mesa_find_temp_intervals() public --- src/mesa/shader/prog_optimize.c | 154 ++++++++++++++++++++++++++++++++++------ src/mesa/shader/prog_optimize.h | 12 ++++ 2 files changed, 144 insertions(+), 22 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c index 6ba2e76ff9..a02f5efa41 100644 --- a/src/mesa/shader/prog_optimize.c +++ b/src/mesa/shader/prog_optimize.c @@ -547,15 +547,13 @@ update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic) /** - * Find the live intervals for each temporary register in the program. - * For register R, the interval [A,B] indicates that R is referenced - * from instruction A through instruction B. - * Special consideration is needed for loops and subroutines. - * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason + * Find first/last instruction that references each temporary register. */ -static GLboolean -find_live_intervals(struct gl_program *prog, - struct interval_list *liveIntervals) +GLboolean +_mesa_find_temp_intervals(const struct prog_instruction *instructions, + GLuint numInstructions, + GLint intBegin[MAX_PROGRAM_TEMPS], + GLint intEnd[MAX_PROGRAM_TEMPS]) { struct loop_info { @@ -563,26 +561,15 @@ find_live_intervals(struct gl_program *prog, }; struct loop_info loopStack[MAX_LOOP_NESTING]; GLuint loopStackDepth = 0; - GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; GLuint i; - /* - * Note: we'll return GL_FALSE below if we find relative indexing - * into the TEMP register file. We can't handle that yet. - * We also give up on subroutines for now. - */ - - if (dbg) { - _mesa_printf("Optimize: Begin find intervals\n"); - } - for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ intBegin[i] = intEnd[i] = -1; } /* Scan instructions looking for temporary registers */ - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < numInstructions; i++) { + const struct prog_instruction *inst = instructions + i; if (inst->Opcode == OPCODE_BGNLOOP) { loopStack[loopStackDepth].Start = i; loopStack[loopStackDepth].End = inst->BranchTarget; @@ -595,7 +582,7 @@ find_live_intervals(struct gl_program *prog, return GL_FALSE; } else { - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); + const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/ GLuint j; for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { @@ -624,6 +611,39 @@ find_live_intervals(struct gl_program *prog, } } + return GL_TRUE; +} + + +/** + * Find the live intervals for each temporary register in the program. + * For register R, the interval [A,B] indicates that R is referenced + * from instruction A through instruction B. + * Special consideration is needed for loops and subroutines. + * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason + */ +static GLboolean +find_live_intervals(struct gl_program *prog, + struct interval_list *liveIntervals) +{ + GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; + GLuint i; + + /* + * Note: we'll return GL_FALSE below if we find relative indexing + * into the TEMP register file. We can't handle that yet. + * We also give up on subroutines for now. + */ + + if (dbg) { + _mesa_printf("Optimize: Begin find intervals\n"); + } + + /* build intermediate arrays */ + if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions, + intBegin, intEnd)) + return GL_FALSE; + /* Build live intervals list from intermediate arrays */ liveIntervals->Num = 0; for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { @@ -794,6 +814,96 @@ _mesa_reallocate_registers(struct gl_program *prog) + + + + +#if 0 +static void +_mesa_find_temporary_live_intervals(struct gl_program *prog, + GLint firstInst[MAX_PROGRAM_TEMPS], + GLint lastInst[MAX_PROGRAM_TEMPS]) +{ + GLuint i; + + for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { + firstInst[i] = lastInst[i] = -1; + } + + struct loop_info loopStack[MAX_LOOP_NESTING]; + GLuint loopStackDepth = 0; + GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; + GLuint i; + + /* + * Note: we'll return GL_FALSE below if we find relative indexing + * into the TEMP register file. We can't handle that yet. + * We also give up on subroutines for now. + */ + + if (dbg) { + _mesa_printf("Optimize: Begin find intervals\n"); + } + + for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ + intBegin[i] = intEnd[i] = -1; + } + + /* Scan instructions looking for temporary registers */ + for (i = 0; i < prog->NumInstructions; i++) { + const struct prog_instruction *inst = prog->Instructions + i; + if (inst->Opcode == OPCODE_BGNLOOP) { + loopStack[loopStackDepth].Start = i; + loopStack[loopStackDepth].End = inst->BranchTarget; + loopStackDepth++; + } + else if (inst->Opcode == OPCODE_ENDLOOP) { + loopStackDepth--; + } + else if (inst->Opcode == OPCODE_CAL) { + return GL_FALSE; + } + else { + const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); + GLuint j; + for (j = 0; j < numSrc; j++) { + if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { + const GLuint index = inst->SrcReg[j].Index; + if (inst->SrcReg[j].RelAddr) + return GL_FALSE; + update_interval(intBegin, intEnd, index, i); + if (loopStackDepth > 0) { + /* extend temp register's interval to end of loop */ + GLuint loopEnd = loopStack[loopStackDepth - 1].End; + update_interval(intBegin, intEnd, index, loopEnd); + } + } + } + if (inst->DstReg.File == PROGRAM_TEMPORARY) { + const GLuint index = inst->DstReg.Index; + if (inst->DstReg.RelAddr) + return GL_FALSE; + update_interval(intBegin, intEnd, index, i); + if (loopStackDepth > 0) { + /* extend temp register's interval to end of loop */ + GLuint loopEnd = loopStack[loopStackDepth - 1].End; + update_interval(intBegin, intEnd, index, loopEnd); + } + } + } + } + + + + +#endif + + + + + + + /** * Apply optimizations to the given program to eliminate unnecessary * instructions, temp regs, etc. diff --git a/src/mesa/shader/prog_optimize.h b/src/mesa/shader/prog_optimize.h index d102cfd9fc..43894a2723 100644 --- a/src/mesa/shader/prog_optimize.h +++ b/src/mesa/shader/prog_optimize.h @@ -25,7 +25,19 @@ #ifndef PROG_OPT_H #define PROG_OPT_H + +#include "main/config.h" + + struct gl_program; +struct prog_instruction; + + +extern GLboolean +_mesa_find_temp_intervals(const struct prog_instruction *instructions, + GLuint numInstructions, + GLint intBegin[MAX_PROGRAM_TEMPS], + GLint intEnd[MAX_PROGRAM_TEMPS]); extern void _mesa_optimize_program(GLcontext *ctx, struct gl_program *program); -- cgit v1.2.3 From b58b3a786aa38dcc9d72144c2cc691151e46e3d5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 16:33:46 -0600 Subject: i965: rework GLSL/WM register allocation Use a bitvector of used/free flags. If we run out of temps, examine the live intervals of the temp regs in the program and free those which are no longer alive. Also, enable the new WM const buffer code. --- src/mesa/drivers/dri/i965/brw_wm.h | 5 +- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 211 +++++++++++++++++++++++++------- 2 files changed, 168 insertions(+), 48 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index d0ab3bdc65..75205fddb7 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -240,15 +240,18 @@ struct brw_wm_compile { GLuint max_wm_grf; GLuint last_scratch; + GLuint cur_inst; /**< index of current instruction */ + /** Mapping from Mesa registers to hardware registers */ struct { GLboolean inited; struct brw_reg reg; } wm_regs[PROGRAM_PAYLOAD+1][256][4]; + GLboolean used_grf[BRW_WM_MAX_GRF]; + GLuint first_free_grf; struct brw_reg stack; struct brw_reg emit_mask_reg; - GLuint reg_index; /**< Index of next free GRF register */ GLuint tmp_regs[BRW_WM_MAX_GRF]; GLuint tmp_index; GLuint tmp_max; diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 22e17622c6..3471c1946e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -1,5 +1,7 @@ #include "main/macros.h" #include "shader/prog_parameter.h" +#include "shader/prog_print.h" +#include "shader/prog_optimize.h" #include "brw_context.h" #include "brw_eu.h" #include "brw_wm.h" @@ -42,6 +44,76 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp) } + +static void +reclaim_temps(struct brw_wm_compile *c); + + +/** Mark GRF register as used. */ +static void +prealloc_grf(struct brw_wm_compile *c, int r) +{ + c->used_grf[r] = GL_TRUE; +} + + +/** Mark given GRF register as not in use. */ +static void +release_grf(struct brw_wm_compile *c, int r) +{ + /*assert(c->used_grf[r]);*/ + c->used_grf[r] = GL_FALSE; + c->first_free_grf = MIN2(c->first_free_grf, r); +} + + +/** Return index of a free GRF, mark it as used. */ +static int +alloc_grf(struct brw_wm_compile *c) +{ + GLuint r; + for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) { + if (!c->used_grf[r]) { + c->used_grf[r] = GL_TRUE; + c->first_free_grf = r + 1; /* a guess */ + return r; + } + } + + /* no free temps, try to reclaim some */ + reclaim_temps(c); + c->first_free_grf = 0; + + /* try alloc again */ + for (r = c->first_free_grf; r < BRW_WM_MAX_GRF; r++) { + if (!c->used_grf[r]) { + c->used_grf[r] = GL_TRUE; + c->first_free_grf = r + 1; /* a guess */ + return r; + } + } + + for (r = 0; r < BRW_WM_MAX_GRF; r++) { + assert(c->used_grf[r]); + } + /*printf("Really out of temp regs!\n");*/ + return 60; +} + + +/** Return number of GRF registers used */ +static int +num_grf_used(const struct brw_wm_compile *c) +{ + int r; + for (r = BRW_WM_MAX_GRF - 1; r >= 0; r--) + if (c->used_grf[r]) + return r + 1; + return 0; +} + + + /** * Record the mapping of a Mesa register to a hardware register. */ @@ -68,11 +140,18 @@ static int get_scalar_dst_index(const struct prog_instruction *inst) static struct brw_reg alloc_tmp(struct brw_wm_compile *c) { struct brw_reg reg; - if(c->tmp_index == c->tmp_max) - c->tmp_regs[ c->tmp_max++ ] = c->reg_index++; - + + /* if we need to allocate another temp, grow the tmp_regs[] array */ + if (c->tmp_index == c->tmp_max) { + c->tmp_regs[ c->tmp_max++ ] = alloc_grf(c); + } + + /* form the GRF register */ reg = brw_vec8_grf(c->tmp_regs[ c->tmp_index++ ], 0); + /*printf("alloc_temp %d\n", reg.nr);*/ + assert(reg.nr < BRW_WM_MAX_GRF); return reg; + } /** @@ -130,35 +209,26 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, return brw_null_reg(); } + assert(index < 256); /* see if we've already allocated a HW register for this Mesa register */ if (c->wm_regs[file][index][component].inited) { - /* yes, re-use */ - reg = c->wm_regs[file][index][component].reg; + /* yes, re-use */ + reg = c->wm_regs[file][index][component].reg; } else { /* no, allocate new register */ - reg = brw_vec8_grf(c->reg_index, 0); - } + int grf = alloc_grf(c); + if (grf < 0) { + /* totally out of temps */ + grf = 70; /* XXX !!!! */ + } - /* if this is a new register allocation, record it in the table */ - if (!c->wm_regs[file][index][component].inited) { - set_reg(c, file, index, component, reg); - c->reg_index++; - } + reg = brw_vec8_grf(grf, 0); + /*printf("Alloc new grf %d for %d.%d\n", reg.nr, index, component);*/ - if (c->reg_index >= BRW_WM_MAX_GRF - 12) { - /* ran out of temporary registers! */ -#if 1 - /* This is a big hack for now. - * Return bad register index, just don't hang the GPU. - */ - _mesa_fprintf(stderr, "out of regs %d\n", c->reg_index); - c->reg_index = BRW_WM_MAX_GRF - 13; -#else - return brw_null_reg(); -#endif + set_reg(c, file, index, component, reg); } - + if (neg & (1 << component)) { reg = negate(reg); } @@ -168,6 +238,46 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, } + +/** + * This is called if we run out of GRF registers. Examine the live intervals + * of temp regs in the program and free those which won't be used again. + */ +static void +reclaim_temps(struct brw_wm_compile *c) +{ + GLint intBegin[MAX_PROGRAM_TEMPS]; + GLint intEnd[MAX_PROGRAM_TEMPS]; + int index; + + /*printf("Reclaim temps:\n");*/ + + _mesa_find_temp_intervals(c->prog_instructions, c->nr_fp_insns, + intBegin, intEnd); + + for (index = 0; index < MAX_PROGRAM_TEMPS; index++) { + if (intEnd[index] != -1 && intEnd[index] < c->cur_inst) { + /* program temp[i] can be freed */ + int component; + /*printf(" temp[%d] is dead\n", index);*/ + for (component = 0; component < 4; component++) { + if (c->wm_regs[PROGRAM_TEMPORARY][index][component].inited) { + int r = c->wm_regs[PROGRAM_TEMPORARY][index][component].reg.nr; + release_grf(c, r); + /* + printf(" Reclaim temp %d, reg %d at inst %d\n", + index, r, c->cur_inst); + */ + c->wm_regs[PROGRAM_TEMPORARY][index][component].inited = GL_FALSE; + } + } + } + } +} + + + + /** * Preallocate registers. This sets up the Mesa to hardware register * mapping for certain registers, such as constants (uniforms/state vars) @@ -179,6 +289,10 @@ static void prealloc_reg(struct brw_wm_compile *c) struct brw_reg reg; int nr_interp_regs = 0; GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted; + GLuint reg_index = 0; + + memset(c->used_grf, GL_FALSE, sizeof(c->used_grf)); + c->first_free_grf = 0; for (i = 0; i < 4; i++) { if (i < c->key.nr_depth_regs) @@ -187,14 +301,20 @@ static void prealloc_reg(struct brw_wm_compile *c) reg = brw_vec8_grf(0, 0); set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg); } - c->reg_index += 2 * c->key.nr_depth_regs; + reg_index += 2 * c->key.nr_depth_regs; /* constants */ { - const int nr_params = c->fp->program.Base.Parameters->NumParameters; + const GLuint nr_params = c->fp->program.Base.Parameters->NumParameters; + const GLuint nr_temps = c->fp->program.Base.NumTemporaries; /* use a real constant buffer, or just use a section of the GRF? */ - c->use_const_buffer = GL_FALSE; /* (nr_params > 8);*/ + /* XXX this heuristic may need adjustment... */ + if ((nr_params + nr_temps) * 4 + reg_index > 80) + c->use_const_buffer = GL_TRUE; + else + c->use_const_buffer = GL_FALSE; + /*printf("WM use_const_buffer = %d\n", c->use_const_buffer);*/ if (c->use_const_buffer) { /* We'll use a real constant buffer and fetch constants from @@ -216,7 +336,7 @@ static void prealloc_reg(struct brw_wm_compile *c) for (i = 0; i < nr_params; i++) { /* loop over XYZW channels */ for (j = 0; j < 4; j++, index++) { - reg = brw_vec1_grf(c->reg_index + index / 8, index % 8); + reg = brw_vec1_grf(reg_index + index / 8, index % 8); /* Save pointer to parameter/constant value. * Constants will be copied in prepare_constant_buffer() */ @@ -226,7 +346,7 @@ static void prealloc_reg(struct brw_wm_compile *c) } /* number of constant regs used (each reg is float[8]) */ c->nr_creg = 2 * ((4 * nr_params + 15) / 16); - c->reg_index += c->nr_creg; + reg_index += c->nr_creg; } } @@ -234,20 +354,24 @@ static void prealloc_reg(struct brw_wm_compile *c) for (i = 0; i < FRAG_ATTRIB_MAX; i++) { if (inputs & (1<reg_index, 0); + reg = brw_vec8_grf(reg_index, 0); for (j = 0; j < 4; j++) set_reg(c, PROGRAM_PAYLOAD, i, j, reg); - c->reg_index += 2; + reg_index += 2; } } c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2; c->prog_data.urb_read_length = nr_interp_regs * 2; c->prog_data.curb_read_length = c->nr_creg; - c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); - c->reg_index++; - c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); - c->reg_index += 2; + c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0); + reg_index++; + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0); + reg_index += 2; + + /* mark GRF regs [0..reg_index-1] as in-use */ + for (i = 0; i < reg_index; i++) + prealloc_grf(c, i); /* An instruction may reference up to three constants. * They'll be found in these registers. @@ -256,13 +380,9 @@ static void prealloc_reg(struct brw_wm_compile *c) if (c->use_const_buffer) { for (i = 0; i < 3; i++) { c->current_const[i].index = -1; - c->current_const[i].reg = alloc_tmp(c); + c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0); } } -#if 0 - printf("USE CONST BUFFER? %d\n", c->use_const_buffer); - printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index); -#endif } @@ -2595,7 +2715,6 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) struct brw_compile *p = &c->func; struct brw_indirect stack_index = brw_indirect(0, 0); - c->reg_index = 0; prealloc_reg(c); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); @@ -2603,6 +2722,8 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) for (i = 0; i < c->nr_fp_insns; i++) { const struct prog_instruction *inst = &c->prog_instructions[i]; + c->cur_inst = i; + #if 0 _mesa_printf("Inst %d: ", i); _mesa_print_instruction(inst); @@ -2833,17 +2954,13 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) _mesa_printf("unsupported IR in fragment shader %d\n", inst->Opcode); } + if (inst->CondUpdate) brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); else brw_set_predicate_control(p, BRW_PREDICATE_NONE); } post_wm_emit(c); - - if (c->reg_index >= BRW_WM_MAX_GRF) { - _mesa_problem(NULL, "Ran out of registers in brw_wm_emit_glsl()"); - /* XXX we need to do some proper error recovery here */ - } } @@ -2867,6 +2984,6 @@ void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c) brw_wm_print_program(c, "brw_wm_glsl_emit done"); } - c->prog_data.total_grf = c->reg_index; + c->prog_data.total_grf = num_grf_used(c); c->prog_data.total_scratch = 0; } -- cgit v1.2.3 From 5ed7764fd6354da8e2be15d6fb724c2d6be9be4a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 14:42:23 +0100 Subject: mesa/st: fix incorrect face, level in compress_with_blit We were incorrectly applying the destination texture face and level when requesting a transfer to the temporary texture, which has only one face and level. This would obviously cause problems uploading to compressed cube and mipmap textures. --- src/mesa/state_tracker/st_cb_texture.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c3e990e077..aeb75117ec 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -418,7 +418,6 @@ compress_with_blit(GLcontext * ctx, const GLuint dstImageOffsets[1] = {0}; struct st_texture_image *stImage = st_texture_image(texImage); struct pipe_screen *screen = ctx->st->pipe->screen; - const GLuint face = _mesa_tex_target_to_face(target); const struct gl_texture_format *mesa_format; struct pipe_texture templ; struct pipe_texture *src_tex; @@ -467,7 +466,7 @@ compress_with_blit(GLcontext * ctx, /* Put user's tex data into the temporary texture */ tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex, - face, level, 0, + 0, 0, 0, /* face, level are zero */ PIPE_TRANSFER_WRITE, 0, 0, width, height); /* x, y, w, h */ map = screen->transfer_map(screen, tex_xfer); -- cgit v1.2.3 From dc9705d12d162ba6d087eb762e315de9f97bc456 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 27 Apr 2009 09:51:46 -0600 Subject: i965: only upload constant buffer data when we actually need the const buffer Make the use_const_buffer field per-program and only call the code which updates the constant buffer's data if the flag is set. This should undo the perf regression from 20f3497e4b6756e330f7b3f54e8acaa1d6c92052 --- src/mesa/drivers/dri/i965/brw_context.h | 2 ++ src/mesa/drivers/dri/i965/brw_curbe.c | 6 ++++-- src/mesa/drivers/dri/i965/brw_vs.h | 2 -- src/mesa/drivers/dri/i965/brw_vs_emit.c | 10 +++++----- src/mesa/drivers/dri/i965/brw_wm.h | 2 -- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 12 ++++++------ 6 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a0b3b06309..aef2ff5f86 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -161,6 +161,7 @@ struct brw_vertex_program { struct gl_vertex_program program; GLuint id; dri_bo *const_buffer; /** Program constant buffer/surface */ + GLboolean use_const_buffer; }; @@ -171,6 +172,7 @@ struct brw_fragment_program { GLboolean isGLSL; /**< really, any IF/LOOP/CONT/BREAK instructions */ dri_bo *const_buffer; /** Program constant buffer/surface */ + GLboolean use_const_buffer; }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 2d15793078..9197fede2d 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -383,7 +383,8 @@ update_vertex_constant_buffer(struct brw_context *brw) printf("update VS constants in buffer %p\n", vp->const_buffer); printf("program %u\n", vp->program.Base.Id); } - update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); + if (vp->use_const_buffer) + update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); } @@ -393,7 +394,8 @@ update_fragment_constant_buffer(struct brw_context *brw) { struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; - update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); + if (fp->use_const_buffer) + update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index d20cf78b8a..1e4f66091e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -75,8 +75,6 @@ struct brw_vs_compile { struct brw_reg userplane[6]; - /** using a real constant buffer? */ - GLboolean use_const_buffer; /** we may need up to 3 constants per instruction (if use_const_buffer) */ struct { GLint index; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 524f1211ce..b69616d6e5 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -71,10 +71,10 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) #if 0 if (c->vp->program.Base.Parameters->NumParameters >= 6) - c->use_const_buffer = 1; + c->vp->use_const_buffer = 1; else #endif - c->use_const_buffer = GL_FALSE; + c->vp->use_const_buffer = GL_FALSE; /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/ /* r0 -- reserved as usual @@ -96,7 +96,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) /* Vertex program parameters from curbe: */ - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { /* get constants from a real constant buffer */ c->prog_data.curb_read_length = 0; c->prog_data.nr_params = 4; /* XXX 0 causes a bug elsewhere... */ @@ -172,7 +172,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) reg++; } - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { for (i = 0; i < 3; i++) { c->current_const[i].index = -1; c->current_const[i].reg = brw_vec8_grf(reg, 0); @@ -869,7 +869,7 @@ get_src_reg( struct brw_vs_compile *c, case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { return get_constant(c, inst, argIndex); } else if (relAddr) { diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index d0ab3bdc65..f0d31fc1dd 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -254,8 +254,6 @@ struct brw_wm_compile { GLuint tmp_max; GLuint subroutines[BRW_WM_MAX_SUBROUTINE]; - /** using a real constant buffer? */ - GLboolean use_const_buffer; /** we may need up to 3 constants per instruction (if use_const_buffer) */ struct { GLint index; diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 22e17622c6..117460842a 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -194,9 +194,9 @@ static void prealloc_reg(struct brw_wm_compile *c) const int nr_params = c->fp->program.Base.Parameters->NumParameters; /* use a real constant buffer, or just use a section of the GRF? */ - c->use_const_buffer = GL_FALSE; /* (nr_params > 8);*/ + c->fp->use_const_buffer = GL_FALSE; /* (nr_params > 8);*/ - if (c->use_const_buffer) { + if (c->fp->use_const_buffer) { /* We'll use a real constant buffer and fetch constants from * it with a dataport read message. */ @@ -253,14 +253,14 @@ static void prealloc_reg(struct brw_wm_compile *c) * They'll be found in these registers. * XXX alloc these on demand! */ - if (c->use_const_buffer) { + if (c->fp->use_const_buffer) { for (i = 0; i < 3; i++) { c->current_const[i].index = -1; c->current_const[i].reg = alloc_tmp(c); } } #if 0 - printf("USE CONST BUFFER? %d\n", c->use_const_buffer); + printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer); printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index); #endif } @@ -368,7 +368,7 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c, const GLuint nr = 1; const GLuint component = GET_SWZ(src->Swizzle, channel); - if (c->use_const_buffer && + if (c->fp->use_const_buffer && (src->File == PROGRAM_STATE_VAR || src->File == PROGRAM_CONSTANT || src->File == PROGRAM_UNIFORM)) { @@ -2609,7 +2609,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) #endif /* fetch any constants that this instruction needs */ - if (c->use_const_buffer) + if (c->fp->use_const_buffer) fetch_constants(c, inst); if (inst->CondUpdate) -- cgit v1.2.3 From 777b9ff43e88e456d686208c83712f26aba2dd95 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 27 Apr 2009 10:45:41 -0600 Subject: i965: only upload constant buffer data when we actually need the const buffer Make the use_const_buffer field per-program and only call the code which updates the constant buffer's data if the flag is set. This should undo the perf regression from 20f3497e4b6756e330f7b3f54e8acaa1d6c92052 (cherry picked from master, commit dc9705d12d162ba6d087eb762e315de9f97bc456) --- src/mesa/drivers/dri/i965/brw_context.h | 2 ++ src/mesa/drivers/dri/i965/brw_curbe.c | 6 ++++-- src/mesa/drivers/dri/i965/brw_vs.h | 2 -- src/mesa/drivers/dri/i965/brw_vs_emit.c | 11 ++++++----- src/mesa/drivers/dri/i965/brw_wm.h | 2 -- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 16 ++++++++++------ 6 files changed, 22 insertions(+), 17 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index f0d4993e11..838e718d0d 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -161,6 +161,7 @@ struct brw_vertex_program { struct gl_vertex_program program; GLuint id; dri_bo *const_buffer; /** Program constant buffer/surface */ + GLboolean use_const_buffer; }; @@ -171,6 +172,7 @@ struct brw_fragment_program { GLboolean isGLSL; /**< really, any IF/LOOP/CONT/BREAK instructions */ dri_bo *const_buffer; /** Program constant buffer/surface */ + GLboolean use_const_buffer; }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index da746e4aa0..e6e26cdc40 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -368,7 +368,8 @@ update_vertex_constant_buffer(struct brw_context *brw) printf("update VS constants in buffer %p vp = %p\n", vp->const_buffer, vp); printf("program %u\n", vp->program.Base.Id); } - update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); + if (vp->use_const_buffer) + update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); } @@ -382,7 +383,8 @@ update_fragment_constant_buffer(struct brw_context *brw) printf("update WM constants in buffer %p\n", fp->const_buffer); printf("program %u\n", fp->program.Base.Id); } - update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); + if (fp->use_const_buffer) + update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index d20cf78b8a..1e4f66091e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -75,8 +75,6 @@ struct brw_vs_compile { struct brw_reg userplane[6]; - /** using a real constant buffer? */ - GLboolean use_const_buffer; /** we may need up to 3 constants per instruction (if use_const_buffer) */ struct { GLint index; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index c2b3702798..b9a338b1cd 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -76,9 +76,10 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) */ if (c->vp->program.Base.Parameters->NumParameters + c->vp->program.Base.NumTemporaries + 20 > BRW_MAX_GRF) - c->use_const_buffer = GL_TRUE; + c->vp->use_const_buffer = GL_TRUE; else - c->use_const_buffer = GL_FALSE; + c->vp->use_const_buffer = GL_FALSE; + /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/ /* r0 -- reserved as usual @@ -100,7 +101,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) /* Vertex program parameters from curbe: */ - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { /* get constants from a real constant buffer */ c->prog_data.curb_read_length = 0; c->prog_data.nr_params = 4; /* XXX 0 causes a bug elsewhere... */ @@ -176,7 +177,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) reg++; } - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { for (i = 0; i < 3; i++) { c->current_const[i].index = -1; c->current_const[i].reg = brw_vec8_grf(reg, 0); @@ -873,7 +874,7 @@ get_src_reg( struct brw_vs_compile *c, case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: - if (c->use_const_buffer) { + if (c->vp->use_const_buffer) { return get_constant(c, inst, argIndex); } else if (relAddr) { diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 75205fddb7..2f80a60c12 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -257,8 +257,6 @@ struct brw_wm_compile { GLuint tmp_max; GLuint subroutines[BRW_WM_MAX_SUBROUTINE]; - /** using a real constant buffer? */ - GLboolean use_const_buffer; /** we may need up to 3 constants per instruction (if use_const_buffer) */ struct { GLint index; diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 3471c1946e..eca4ca2c82 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -311,12 +311,12 @@ static void prealloc_reg(struct brw_wm_compile *c) /* use a real constant buffer, or just use a section of the GRF? */ /* XXX this heuristic may need adjustment... */ if ((nr_params + nr_temps) * 4 + reg_index > 80) - c->use_const_buffer = GL_TRUE; + c->fp->use_const_buffer = GL_TRUE; else - c->use_const_buffer = GL_FALSE; + c->fp->use_const_buffer = GL_FALSE; /*printf("WM use_const_buffer = %d\n", c->use_const_buffer);*/ - if (c->use_const_buffer) { + if (c->fp->use_const_buffer) { /* We'll use a real constant buffer and fetch constants from * it with a dataport read message. */ @@ -377,12 +377,16 @@ static void prealloc_reg(struct brw_wm_compile *c) * They'll be found in these registers. * XXX alloc these on demand! */ - if (c->use_const_buffer) { + if (c->fp->use_const_buffer) { for (i = 0; i < 3; i++) { c->current_const[i].index = -1; c->current_const[i].reg = brw_vec8_grf(alloc_grf(c), 0); } } +#if 0 + printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer); + printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index); +#endif } @@ -488,7 +492,7 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c, const GLuint nr = 1; const GLuint component = GET_SWZ(src->Swizzle, channel); - if (c->use_const_buffer && + if (c->fp->use_const_buffer && (src->File == PROGRAM_STATE_VAR || src->File == PROGRAM_CONSTANT || src->File == PROGRAM_UNIFORM)) { @@ -2730,7 +2734,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) #endif /* fetch any constants that this instruction needs */ - if (c->use_const_buffer) + if (c->fp->use_const_buffer) fetch_constants(c, inst); if (inst->CondUpdate) -- cgit v1.2.3 From dd4802176f7751e8c38c000687ff9cb9633649aa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 27 Apr 2009 10:46:30 -0600 Subject: i965: #include prog_print.h to silence warning --- src/mesa/drivers/dri/i965/brw_curbe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index e6e26cdc40..f6d2014fb1 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -36,6 +36,7 @@ #include "main/macros.h" #include "main/enums.h" #include "shader/prog_parameter.h" +#include "shader/prog_print.h" #include "shader/prog_statevars.h" #include "intel_batchbuffer.h" #include "intel_regions.h" -- cgit v1.2.3 From 359a58230e0644a39c1904a74bc25803dc6cab6f Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Mon, 27 Apr 2009 12:08:34 -0600 Subject: Avoid a segfault in shader compilation If a shader reaches an out-of-memory condition while adding a new function (reallocating the function list), a segfault will occur during cleanup (because the num_functions field is non-zero, but the functions pointer is NULL). This fixes that segfault by zeroing out the num_functions field if reallocation fails. --- src/mesa/shader/slang/slang_compile.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index ba2fc4f85c..d7ad879e97 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -2161,6 +2161,12 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, (O->funs->num_functions + 1) * sizeof(slang_function)); if (O->funs->functions == NULL) { + /* Make sure that there are no functions marked, as the + * allocation is currently NULL, in order to avoid + * a potental segfault as we clean up later. + */ + O->funs->num_functions = 0; + slang_info_log_memory(C->L); slang_function_destruct(&parsed_func); return GL_FALSE; -- cgit v1.2.3 From 3d2bba0d10d59a9c2d6d09c5dc3fabe148d5e0d7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 28 Apr 2009 14:12:39 +0200 Subject: st: Add an st_get_current() function. Signed-off-by: Thomas Hellstrom --- src/mesa/state_tracker/st_context.c | 6 ++++++ src/mesa/state_tracker/st_public.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index b27274725f..92a630eff9 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -279,6 +279,12 @@ void st_make_current(struct st_context *st, } } +struct st_context *st_get_current(void) +{ + GET_CURRENT_CONTEXT(ctx); + + return (ctx == NULL) ? NULL : ctx->st; +} void st_copy_context_state(struct st_context *dst, struct st_context *src, diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 030314372f..290b8a974e 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -95,6 +95,8 @@ void st_make_current(struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read); +struct st_context *st_get_current(void); + void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ); void st_finish( struct st_context *st ); -- cgit v1.2.3 From dcf571aff9de1a4298c4d2c4148d84cdc4daf02e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 28 Apr 2009 09:05:19 -0600 Subject: swrast: add missing break in clamp_rect_coord_linear() See bug 21461. --- src/mesa/swrast/s_texfilter.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa') diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index a483023a50..31bfb5c952 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -462,6 +462,7 @@ clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, fcol -= 0.5F; i0 = IFLOOR(fcol); i1 = i0 + 1; + break; default: _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); i0 = i1 = 0; -- cgit v1.2.3 From 43d9020ff1e975e7f4f9480d9ef24f0b9fb2141f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 28 Apr 2009 09:58:44 -0600 Subject: i965: avoid segfault in intel_update_renderbuffers() if using DRI1 --- src/mesa/drivers/dri/intel/intel_context.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index eb224a8a41..a6d8729d8f 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -198,7 +198,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) struct intel_renderbuffer *rb; struct intel_region *region, *depth_region; struct intel_context *intel = context->driverPrivate; - __DRIbuffer *buffers; + __DRIbuffer *buffers = NULL; __DRIscreen *screen; int i, count; unsigned int attachments[10]; @@ -210,7 +210,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = intel->intelScreen->driScrnPriv; - if ((screen->dri2.loader->base.version > 2) + if (screen->dri2.loader + && (screen->dri2.loader->base.version > 2) && (screen->dri2.loader->getBuffersWithFormat != NULL)) { struct intel_renderbuffer *depth_rb; struct intel_renderbuffer *stencil_rb; @@ -248,7 +249,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) attachments, i / 2, &count, drawable->loaderPrivate); - } else { + } else if (screen->dri2.loader) { i = 0; if (intel_fb->color_rb[0]) attachments[i++] = __DRI_BUFFER_FRONT_LEFT; -- cgit v1.2.3 From 09c91a1565fc99f20379a0f552651303ae8067c2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 28 Apr 2009 12:37:29 -0400 Subject: R300: add quadpipe overrides RV410 SE chips only have 1 quadpipe. Also, handle other R300 chip with quadpipe override --- src/mesa/drivers/dri/radeon/radeon_screen.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 882853344b..791f59826b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -561,11 +561,8 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) screen->chip_family = CHIP_FAMILY_RS300; break; - /* 9500 with 1 pipe verified by: Reid Linnemann */ + case PCI_CHIP_R300_AD: - screen->chip_family = CHIP_FAMILY_RV350; - screen->chip_flags = RADEON_CHIPSET_TCL; - break; case PCI_CHIP_R300_AE: case PCI_CHIP_R300_AF: case PCI_CHIP_R300_AG: @@ -893,6 +890,18 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv ) } else { screen->num_gb_pipes = temp; } + + /* pipe overrides */ + switch (dri_priv->deviceID) { + case PCI_CHIP_R300_AD: /* 9500 with 1 quadpipe verified by: Reid Linnemann */ + case PCI_CHIP_RV410_5E4C: /* RV410 SE only have 1 quadpipe */ + case PCI_CHIP_RV410_5E4F: /* RV410 SE only have 1 quadpipe */ + screen->num_gb_pipes = 1; + break; + default: + break; + } + } if ( sPriv->drm_version.minor >= 10 ) { -- cgit v1.2.3 From afd16512bc354cf1a7220cb9bf3ce445503c7af4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 18:56:26 +0100 Subject: mesa/st: workaround for crashes in st_copy_texsubimage Proper fix for this hasn't been identified, but avoid crashing. --- src/mesa/state_tracker/st_cb_texture.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index aeb75117ec..b7b791d9a4 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -51,6 +51,7 @@ #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" #include "state_tracker/st_inlines.h" +#include "state_tracker/st_atom.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -1317,6 +1318,10 @@ st_copy_texsubimage(GLcontext *ctx, /* any rendering in progress must complete before we grab the fb image */ st_finish(ctx->st); + /* make sure finalize_textures has been called? + */ + if (0) st_validate_state(ctx->st); + /* determine if copying depth or color data */ if (texBaseFormat == GL_DEPTH_COMPONENT || texBaseFormat == GL_DEPTH24_STENCIL8) { @@ -1330,6 +1335,11 @@ st_copy_texsubimage(GLcontext *ctx, strb = st_renderbuffer(fb->_ColorReadBuffer); } + if (!strb || !strb->surface || !stImage->pt) { + debug_printf("%s: null strb or stImage\n", __FUNCTION__); + return; + } + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From afc0c59dbd7f89d914763fd78701461f22c00450 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 27 Apr 2009 15:33:44 +0100 Subject: mesa/st: translate VERT_ATTRIB_GENERIC8..15 in st_translate_vertex_program It seems quake4 can hit these attributes sometimes. --- src/mesa/state_tracker/st_program.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 2795570cf1..6ec633c0b4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -169,6 +169,14 @@ st_translate_vertex_program(struct st_context *st, case VERT_ATTRIB_GENERIC5: case VERT_ATTRIB_GENERIC6: case VERT_ATTRIB_GENERIC7: + case VERT_ATTRIB_GENERIC8: + case VERT_ATTRIB_GENERIC9: + case VERT_ATTRIB_GENERIC10: + case VERT_ATTRIB_GENERIC11: + case VERT_ATTRIB_GENERIC12: + case VERT_ATTRIB_GENERIC13: + case VERT_ATTRIB_GENERIC14: + case VERT_ATTRIB_GENERIC15: assert(attr < VERT_ATTRIB_MAX); vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; vs_input_semantic_index[slot] = num_generic++; -- cgit v1.2.3 From 106f2b031cbb83a54fa2949cb07357ecea68b92a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 14:51:11 +0100 Subject: mesa/st: remove duplicate offset calculation --- src/mesa/state_tracker/st_atom_rasterizer.c | 17 +---------------- src/mesa/state_tracker/st_context.h | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 61687fbc3e..4e70510c0c 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -180,22 +180,7 @@ static void update_raster_state( struct st_context *st ) if (ctx->Polygon.StippleFlag) raster->poly_stipple_enable = 1; - - - /* _NEW_BUFFERS, _NEW_POLYGON - */ - if (raster->fill_cw != PIPE_POLYGON_MODE_FILL || - raster->fill_ccw != PIPE_POLYGON_MODE_FILL) - { - GLfloat mrd = (ctx->DrawBuffer ? - ctx->DrawBuffer->_MRD : - 1.0f); - - raster->offset_units = ctx->Polygon.OffsetFactor * mrd; - raster->offset_scale = (ctx->Polygon.OffsetUnits * mrd * - st->polygon_offset_scale); - } - + /* _NEW_POINT */ raster->point_size = ctx->Point.Size; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index f840579a40..6ffed56d9a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -120,8 +120,6 @@ struct st_context GLboolean missing_textures; - GLfloat polygon_offset_scale; /* ?? */ - /** Mapping from VERT_RESULT_x to post-transformed vertex slot */ const GLuint *vertex_result_to_slot; -- cgit v1.2.3 From c0bff53334194f9d1aada23510123f1591d5512e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 17:49:50 +0100 Subject: mesa/main: protect driver.finish with FLUSH_CURRENT Already doing this for driver.flush() --- src/mesa/main/context.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 4469c8e1fa..016284de9a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1497,6 +1497,7 @@ _mesa_Finish(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT( ctx, 0 ); if (ctx->Driver.Finish) { ctx->Driver.Finish(ctx); } -- cgit v1.2.3 From 801a33ae44355b89cebed47e9e48e39545522f6e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 17:50:19 +0100 Subject: mesa/st: protect internal flushes with FLUSH_CURRENT Already doing this for driver.flush() --- src/mesa/state_tracker/st_cb_flush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 7d7d3823c9..fbaffd154f 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -82,7 +82,7 @@ display_front_buffer(struct st_context *st) void st_flush( struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence ) { - FLUSH_VERTICES(st->ctx, 0); + FLUSH_CURRENT(st->ctx, 0); /* Release any vertex buffers that might potentially be accessed in * successive frames: -- cgit v1.2.3 From 0e85dcb66b990a63d60032816798ff693f9248e7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 29 Apr 2009 11:52:06 -0600 Subject: mesa: added _mesa_check_soa_dependencies() function This function will check an instruction to see if there's data dependencies between the dst and src registers if executed in an SOA manner. --- src/mesa/shader/prog_instruction.c | 50 ++++++++++++++++++++++++++++++++++++++ src/mesa/shader/prog_instruction.h | 3 +++ 2 files changed, 53 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index ca7565c091..ae3a003fee 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -285,6 +285,56 @@ _mesa_is_tex_instruction(gl_inst_opcode opcode) } +/** + * Check if there's a potential src/dst register data dependency when + * using SOA execution. + * Example: + * MOV T, T.yxwz; + * This would expand into: + * MOV t0, t1; + * MOV t1, t0; + * MOV t2, t3; + * MOV t3, t2; + * The second instruction will have the wrong value for t0 if executed as-is. + */ +GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst) +{ + GLuint i, chan; + + if (inst->DstReg.WriteMask == WRITEMASK_X || + inst->DstReg.WriteMask == WRITEMASK_Y || + inst->DstReg.WriteMask == WRITEMASK_Z || + inst->DstReg.WriteMask == WRITEMASK_W || + inst->DstReg.WriteMask == 0x0) { + /* no chance of data dependency */ + return GL_FALSE; + } + + /* loop over src regs */ + for (i = 0; i < 3; i++) { + if (inst->SrcReg[i].File == inst->DstReg.File && + inst->SrcReg[i].Index == inst->DstReg.Index) { + /* loop over dest channels */ + GLuint channelsWritten = 0x0; + for (chan = 0; chan < 4; chan++) { + if (inst->DstReg.WriteMask & (1 << chan)) { + /* check if we're reading a channel that's been written */ + GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan); + if (swizzle <= SWIZZLE_W && + (channelsWritten & (1 << swizzle))) { + return GL_TRUE; + } + + channelsWritten |= (1 << chan); + } + } + } + } + return GL_FALSE; +} + + /** * Return string name for given program opcode. */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 3109f6cbae..40ad998f79 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -428,6 +428,9 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode); extern GLboolean _mesa_is_tex_instruction(gl_inst_opcode opcode); +extern GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst); + extern const char * _mesa_opcode_string(gl_inst_opcode opcode); -- cgit v1.2.3 From dca190e9432d4ed122bdd534922d0c3d85791c6a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 29 Apr 2009 11:52:06 -0600 Subject: mesa: added _mesa_check_soa_dependencies() function This function will check an instruction to see if there's data dependencies between the dst and src registers if executed in an SOA manner. --- src/mesa/shader/prog_instruction.c | 50 ++++++++++++++++++++++++++++++++++++++ src/mesa/shader/prog_instruction.h | 3 +++ 2 files changed, 53 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index ca7565c091..ae3a003fee 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -285,6 +285,56 @@ _mesa_is_tex_instruction(gl_inst_opcode opcode) } +/** + * Check if there's a potential src/dst register data dependency when + * using SOA execution. + * Example: + * MOV T, T.yxwz; + * This would expand into: + * MOV t0, t1; + * MOV t1, t0; + * MOV t2, t3; + * MOV t3, t2; + * The second instruction will have the wrong value for t0 if executed as-is. + */ +GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst) +{ + GLuint i, chan; + + if (inst->DstReg.WriteMask == WRITEMASK_X || + inst->DstReg.WriteMask == WRITEMASK_Y || + inst->DstReg.WriteMask == WRITEMASK_Z || + inst->DstReg.WriteMask == WRITEMASK_W || + inst->DstReg.WriteMask == 0x0) { + /* no chance of data dependency */ + return GL_FALSE; + } + + /* loop over src regs */ + for (i = 0; i < 3; i++) { + if (inst->SrcReg[i].File == inst->DstReg.File && + inst->SrcReg[i].Index == inst->DstReg.Index) { + /* loop over dest channels */ + GLuint channelsWritten = 0x0; + for (chan = 0; chan < 4; chan++) { + if (inst->DstReg.WriteMask & (1 << chan)) { + /* check if we're reading a channel that's been written */ + GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan); + if (swizzle <= SWIZZLE_W && + (channelsWritten & (1 << swizzle))) { + return GL_TRUE; + } + + channelsWritten |= (1 << chan); + } + } + } + } + return GL_FALSE; +} + + /** * Return string name for given program opcode. */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 3109f6cbae..40ad998f79 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -428,6 +428,9 @@ _mesa_num_inst_dst_regs(gl_inst_opcode opcode); extern GLboolean _mesa_is_tex_instruction(gl_inst_opcode opcode); +extern GLboolean +_mesa_check_soa_dependencies(const struct prog_instruction *inst); + extern const char * _mesa_opcode_string(gl_inst_opcode opcode); -- cgit v1.2.3 From a9c97c5f2a9b880d01336a23134600e4b34429d0 Mon Sep 17 00:00:00 2001 From: Tom Fogal Date: Wed, 29 Apr 2009 10:32:46 -0600 Subject: Use variable library name in pkg-config output. Previously the pkg-config output files would contain e.g. `-lGL' and `-lGLU', even if the user modified their configuration to build libraries with different names. This modifies the pkg-config inputs, and corresponding makery, so that modifying the output library name will cause the appropriate updated name to appear in the pkg-config `-l' option. Signed-off-by: Dan Nicholson --- src/mesa/Makefile | 3 ++- src/mesa/gl.pc.in | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 4ff28dae9b..bb18bee8ea 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -103,7 +103,8 @@ gl_pcedit = sed \ -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \ -e 's,@GL_PC_REQ_PRIV@,$(GL_PC_REQ_PRIV),' \ -e 's,@GL_PC_LIB_PRIV@,$(GL_PC_LIB_PRIV),' \ - -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' + -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' \ + -e 's,@GL_LIB@,$(GL_LIB),' gl.pc: gl.pc.in $(gl_pcedit) $< > $@ diff --git a/src/mesa/gl.pc.in b/src/mesa/gl.pc.in index 0462b9fca2..97b86596fc 100644 --- a/src/mesa/gl.pc.in +++ b/src/mesa/gl.pc.in @@ -7,6 +7,6 @@ Name: gl Description: Mesa OpenGL library Requires.private: @GL_PC_REQ_PRIV@ Version: @VERSION@ -Libs: -L${libdir} -lGL +Libs: -L${libdir} -l@GL_LIB@ Libs.private: @GL_PC_LIB_PRIV@ Cflags: -I${includedir} @GL_PC_CFLAGS@ -- cgit v1.2.3 From c28707b50701b1cf8727be29d61e2d939c6ee58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 30 Apr 2009 13:21:08 +0200 Subject: r300: Increase reference count of texture objects referenced by current state. Fixes a use-after-free reported in http://bugs.freedesktop.org/show_bug.cgi?id=20539, so this possibly fixes that bug. It has been confirmed to fix http://bugs.freedesktop.org/show_bug.cgi?id=17895 . --- src/mesa/drivers/dri/r300/r300_context.h | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 2 +- src/mesa/drivers/dri/r300/r300_texmem.c | 5 +++-- src/mesa/drivers/dri/r300/r300_texstate.c | 11 ++++++----- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 9c49586998..96a3205f1a 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -215,7 +215,7 @@ struct r300_tex_obj { }; struct r300_texture_env_state { - r300TexObjPtr texobj; + struct gl_texture_object *texobj; GLenum format; GLenum envMode; }; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 6b79aa4313..79f0b3625c 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1362,7 +1362,7 @@ static void r300SetupTextures(GLcontext * ctx) #endif tmu_mappings[i] = hw_tmu; - t = r300->state.texture.unit[i].texobj; + t = (r300TexObjPtr) r300->state.texture.unit[i].texobj->DriverData; /* XXX questionable fix for bug 9170: */ if (!t) continue; diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 0fe51b0c68..a89ab83d94 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -44,6 +44,7 @@ SOFTWARE. #include "main/colormac.h" #include "main/macros.h" #include "main/simple_list.h" +#include "main/texobj.h" #include "radeon_reg.h" /* gets definition for usleep */ #include "r300_context.h" #include "r300_state.h" @@ -71,8 +72,8 @@ void r300DestroyTexObj(r300ContextPtr rmesa, r300TexObjPtr t) } for (i = 0; i < rmesa->radeon.glCtx->Const.MaxTextureUnits; i++) { - if (rmesa->state.texture.unit[i].texobj == t) { - rmesa->state.texture.unit[i].texobj = NULL; + if (rmesa->state.texture.unit[i].texobj == t->base.tObj) { + _mesa_reference_texobj(&rmesa->state.texture.unit[i].texobj, NULL); } } } diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index cadec7f3ec..abe613e27b 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -567,19 +567,20 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit) /* Update state if this is a different texture object to last * time. */ - if (rmesa->state.texture.unit[unit].texobj != t) { + if (rmesa->state.texture.unit[unit].texobj != tObj) { if (rmesa->state.texture.unit[unit].texobj != NULL) { + r300TexObjPtr t_old = (r300TexObjPtr) rmesa->state.texture.unit[unit].texobj->DriverData; + /* The old texture is no longer bound to this texture unit. * Mark it as such. */ - rmesa->state.texture.unit[unit].texobj->base.bound &= - ~(1 << unit); + t_old->base.bound &= ~(1 << unit); } - rmesa->state.texture.unit[unit].texobj = t; + _mesa_reference_texobj(&rmesa->state.texture.unit[unit].texobj, tObj); t->base.bound |= (1 << unit); - driUpdateTextureLRU((driTextureObject *) t); /* XXX: should be locked! */ + driUpdateTextureLRU(&t->base); /* XXX: should be locked! */ } return !t->border_fallback; -- cgit v1.2.3 From 8a488b1be720247339f5c86fea5d2bff3d0fe084 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:19:59 -0600 Subject: mesa: remove -devel suffix from version --- src/mesa/main/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index f5bf6e2c85..ba027465d4 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -31,7 +31,7 @@ #define MESA_MAJOR 7 #define MESA_MINOR 5 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.5-devel" +#define MESA_VERSION_STRING "7.5" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -- cgit v1.2.3 From 666e5bf4a6728484b4bc0c7e2583f141f1f2b2b7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:22:20 -0600 Subject: mesa: bump version to 7.6 (devel) --- src/mesa/main/version.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index f5bf6e2c85..d4d3dd1a94 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.5 + * Version: 7.6 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,9 +30,9 @@ /* Mesa version */ #define MESA_MAJOR 7 -#define MESA_MINOR 5 +#define MESA_MINOR 6 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.5-devel" +#define MESA_VERSION_STRING "7.6-devel" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -- cgit v1.2.3 From 3f25219c7bf0f090502489928f0f018e62c4f6cf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:30:32 -0600 Subject: mesa: create/use a fallback texture when bound texture is incomplete When a GLSL sampler reads from an incomplete texture it should return (0,0,0,1). Instead of jumping through hoops in all the drivers to make this happen, just create/install a fallback texture with those texel values. Fixes piglit/fp-incomplete-tex on i965 and more importantly, fixes some GPU lockups when trying to sample from missing surfaces. If a binding table entry is NULL, it seems that sampling sometimes works, but not always (lockup). Todo: create a fallback texture for each type of texture target? --- src/mesa/main/mtypes.h | 3 +++ src/mesa/main/texobj.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/texobj.h | 3 +++ src/mesa/main/texstate.c | 9 ++++++-- 4 files changed, 66 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 30c7cca3b5..38c3b1bb40 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2050,6 +2050,9 @@ struct gl_shared_state /** Default texture objects (shared by all texture units) */ struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; + /** Fallback texture used when a bound texture is incomplete */ + struct gl_texture_object *FallbackTex; + /** * \name Thread safety and statechange notification for texture * objects. diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index b63f747fe8..0024efc0e6 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -662,6 +662,59 @@ _mesa_test_texobj_completeness( const GLcontext *ctx, } } + +/** + * Return pointer to a default/fallback texture. + * The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1). + * That's the value a sampler should get when sampling from an + * incomplete texture. + */ +struct gl_texture_object * +_mesa_get_fallback_texture(GLcontext *ctx) +{ + if (!ctx->Shared->FallbackTex) { + /* create fallback texture now */ + static GLubyte texels[8 * 8][4]; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLuint i; + + for (i = 0; i < 8 * 8; i++) { + texels[i][0] = + texels[i][1] = + texels[i][2] = 0x0; + texels[i][3] = 0xff; + } + + /* create texture object */ + texObj = ctx->Driver.NewTextureObject(ctx, 0, GL_TEXTURE_2D); + assert(texObj->RefCount == 1); + texObj->MinFilter = GL_NEAREST; + texObj->MagFilter = GL_NEAREST; + + /* create level[0] texture image */ + texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, 0); + + /* init the image fields */ + _mesa_init_teximage_fields(ctx, GL_TEXTURE_2D, texImage, + 8, 8, 1, 0, GL_RGBA); + + /* set image data */ + ctx->Driver.TexImage2D(ctx, GL_TEXTURE_2D, 0, GL_RGBA, + 8, 8, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texels, + &ctx->DefaultPacking, texObj, texImage); + + _mesa_test_texobj_completeness(ctx, texObj); + assert(texObj->_Complete); + + ctx->Shared->FallbackTex = texObj; + } + return ctx->Shared->FallbackTex; +} + + + /*@}*/ diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index d5374c5d6c..2599c0816a 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -65,6 +65,9 @@ extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); +extern struct gl_texture_object * +_mesa_get_fallback_texture(GLcontext *ctx); + extern void _mesa_unlock_context_textures( GLcontext *ctx ); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 73f8a5339e..32d55ba8d5 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -561,8 +561,13 @@ update_texture_state( GLcontext *ctx ) } if (!texUnit->_ReallyEnabled) { - _mesa_reference_texobj(&texUnit->_Current, NULL); - continue; + /* If we get here it means the shader (or fixed-function state) + * is expecting a texture object, but there isn't one (or it's + * incomplete). Use the fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From cd6734288ddc15a778def9578e128184b3f6bdea Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:15:21 -0600 Subject: st: when double buffered, only create front color buffer on demand Before we always created the front color buffer, even if was never used. This can save some memory. --- src/mesa/state_tracker/st_cb_fbo.c | 101 ++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_framebuffer.c | 16 ++--- 2 files changed, 109 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..0b88d9bf7e 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -452,6 +452,104 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Check if we're drawing into, or read from, a front color buffer. If the + * front buffer is missing, create it now. + * + * The back color buffer must exist since we'll use its format/samples info + * for creating the front buffer. + * + * \param frontIndex either BUFFER_FRONT_LEFT or BUFFER_FRONT_RIGHT + * \param backIndex either BUFFER_BACK_LEFT or BUFFER_BACK_RIGHT + */ +static void +check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) +{ + if (fb->Attachment[frontIndex].Renderbuffer == NULL) { + GLboolean create = GL_FALSE; + + /* check if drawing to or reading from front buffer */ + if (fb->_ColorReadBufferIndex == frontIndex) { + create = GL_TRUE; + } + else { + GLuint b; + for (b = 0; b < fb->_NumColorDrawBuffers; b++) { + if (fb->_ColorDrawBufferIndexes[b] == frontIndex) { + create = GL_TRUE; + break; + } + } + } + + if (create) { + struct st_renderbuffer *back; + struct gl_renderbuffer *front; + enum pipe_format colorFormat; + uint samples; + + if (0) + _mesa_debug(ctx, "Allocate new front buffer"); + + /* get back renderbuffer info */ + back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); + colorFormat = back->format; + samples = back->Base.NumSamples; + + /* create front renderbuffer */ + front = st_new_renderbuffer_fb(colorFormat, samples); + _mesa_add_renderbuffer(fb, frontIndex, front); + + /* alloc texture/surface for new front buffer */ + front->AllocStorage(ctx, front, front->InternalFormat, + fb->Width, fb->Height); + } + } +} + + +/** + * If front left/right color buffers are missing, create them now. + */ +static void +check_create_front_buffers(GLcontext *ctx, struct gl_framebuffer *fb) +{ + /* check if we need to create the front left buffer now */ + check_create_front_buffer(ctx, fb, BUFFER_FRONT_LEFT, BUFFER_BACK_LEFT); + + if (fb->Visual.stereoMode) { + check_create_front_buffer(ctx, fb, BUFFER_FRONT_RIGHT, BUFFER_BACK_RIGHT); + } + + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + +/** + * Called via glDrawBuffer. + */ +static void +st_DrawBuffers(GLcontext *ctx, GLsizei count, const GLenum *buffers) +{ + (void) count; + (void) buffers; + check_create_front_buffers(ctx, ctx->DrawBuffer); +} + + +/** + * Called via glReadBuffer. + */ +static void +st_ReadBuffer(GLcontext *ctx, GLenum buffer) +{ + (void) buffer; + check_create_front_buffers(ctx, ctx->ReadBuffer); +} + + void st_init_fbo_functions(struct dd_function_table *functions) { functions->NewFramebuffer = st_new_framebuffer; @@ -464,4 +562,7 @@ void st_init_fbo_functions(struct dd_function_table *functions) /* no longer needed by core Mesa, drivers handle resizes... functions->ResizeBuffers = st_resize_buffers; */ + + functions->DrawBuffers = st_DrawBuffers; + functions->ReadBuffer = st_ReadBuffer; } diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index daaad65cca..6ad64739bd 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -58,19 +58,19 @@ st_create_framebuffer( const __GLcontextModes *visual, _mesa_initialize_framebuffer(&stfb->Base, visual); - { - /* fake frontbuffer */ - /* XXX allocation should only happen in the unusual case - it's actually needed */ + if (visual->doubleBufferMode) { struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); } - - if (visual->doubleBufferMode) { + else { + /* Only allocate front buffer right now if we're single buffered. + * If double-buffered, allocate front buffer on demand later. + * See check_create_front_buffers(). + */ struct gl_renderbuffer *rb = st_new_renderbuffer_fb(colorFormat, samples); - _mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb); + _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb); } if (depthFormat == stencilFormat && depthFormat != PIPE_FORMAT_NONE) { -- cgit v1.2.3 From 2085cf24628be7cd297ab0f9ef5ce02bd5a006e2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 28 Apr 2009 10:08:57 -0700 Subject: Test either GL_FRONT_LEFT or GL_FRONT for front-buffer rendering For non-stereo visuals, which is all we support, we treat GL_FRONT_LEFT as GL_FRONT. However, they are technically different, and they have different enum values. Test for either one to determine if we're in front-buffer rendering mode. This fix was suggested by Pierre Willenbrock. Signed-off-by: Ian Romanick --- src/mesa/drivers/dri/intel/intel_buffers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index ecac5bf020..b86cafea24 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -326,7 +326,8 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode) const GLboolean was_front_buffer_rendering = intel->is_front_buffer_rendering; - intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT); + intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT) + || (mode == GL_FRONT); /* If we weren't front-buffer rendering before but we are now, make sure * that the front-buffer has actually been allocated. -- cgit v1.2.3 From 3534539557350f4a63c6e8b3a48fbc8cacffe199 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 10:50:04 -0600 Subject: set: new st_swapbuffers() which does a true front/back buffer swap The pointers to the front/back renderbuffers are exchanged. This new function isn't actually used yet... --- src/mesa/state_tracker/st_framebuffer.c | 79 +++++++++++++++++++++++++++++++++ src/mesa/state_tracker/st_public.h | 4 ++ 2 files changed, 83 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 6ad64739bd..07ccaa6aab 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -293,6 +293,85 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) } +/** + * Swap the front/back color buffers. Exchange the front/back pointers + * and update some derived state. + * No need to call st_notify_swapbuffers() first. + * This is effectively a no-op for single-buffered framebuffers. + * \param front_left returns pointer to front-left renderbuffer after swap + * \param front_right returns pointer to front-right renderbuffer after swap + */ +void +st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right) +{ + struct gl_framebuffer *fb = &stfb->Base; + + GET_CURRENT_CONTEXT(ctx); + + if (ctx && ctx->DrawBuffer == &stfb->Base) { + st_flush( ctx->st, + PIPE_FLUSH_RENDER_CACHE | + PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_FRAME, + NULL ); + } + + /* swap left buffers */ + if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer = + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer = rbTemp; + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + else { + /* no front buffer, display the back buffer */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + *front_left = strb->surface; + } + } + + /* swap right buffers (for stereo) */ + if (fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer && + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer) { + struct gl_renderbuffer *rbTemp; + rbTemp = fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer = + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer; + fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer = rbTemp; + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb->surface; + } + } + else { + /* no front right buffer, display back right buffer (if exists) */ + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + } + + /* Update the _ColorDrawBuffers[] array and _ColorReadBuffer pointer */ + _mesa_update_framebuffer(ctx); + + /* Make sure we draw into the new back surface */ + st_invalidate_state(ctx, _NEW_BUFFERS); +} + + void *st_framebuffer_private( struct st_framebuffer *stfb ) { return stfb->Private; diff --git a/src/mesa/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h index 290b8a974e..174fbc6394 100644 --- a/src/mesa/state_tracker/st_public.h +++ b/src/mesa/state_tracker/st_public.h @@ -103,6 +103,10 @@ void st_finish( struct st_context *st ); void st_notify_swapbuffers(struct st_framebuffer *stfb); +void st_swapbuffers(struct st_framebuffer *stfb, + struct pipe_surface **front_left, + struct pipe_surface **front_right); + int st_set_teximage(struct pipe_texture *pt, int target); /** Redirect rendering into stfb's surface to a texture image */ -- cgit v1.2.3 From 30b3d800917cc5b41ec508fd38a0ae1da8624a36 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:12:43 -0600 Subject: mesa: fix comment --- src/mesa/main/mtypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 38c3b1bb40..cf71077728 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1028,7 +1028,7 @@ struct gl_stencil_attrib /** * An index for each type of texture object. These correspond to the GL - * target target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. + * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. * Note: the order is from highest priority to lowest priority. */ typedef enum -- cgit v1.2.3 From b85b315ebbe25efbd118887bdc87a562d4334fcc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:25:42 -0600 Subject: st: added st_renderbuffer::defined flag Indicates whether there's defined image contents, or garbage/don't care. This is set when we draw into a renderbuffer and cleared when we resize/ reallocate a renderbuffer or do a buffer swap (back buffer becomes undefined). We use this to determine whether the front color buffer has been drawn to, and whether to display its contents upon glFlush/Finish(), when the new st_swapbuffers() function is used. --- src/mesa/state_tracker/st_atom_framebuffer.c | 1 + src/mesa/state_tracker/st_cb_fbo.c | 2 ++ src/mesa/state_tracker/st_cb_fbo.h | 1 + src/mesa/state_tracker/st_cb_flush.c | 11 ++++++++++- src/mesa/state_tracker/st_context.h | 3 ++- src/mesa/state_tracker/st_framebuffer.c | 12 ++++++++++++ 6 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index df0f0931ea..f23186c73d 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -123,6 +123,7 @@ update_framebuffer_state( struct st_context *st ) framebuffer->cbufs[framebuffer->nr_cbufs] = strb->surface; framebuffer->nr_cbufs++; } + strb->defined = GL_TRUE; /* we'll be drawing something */ } } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 0b88d9bf7e..fe9befaa2c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -125,6 +125,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, strb->Base.Height = height; init_renderbuffer_bits(strb, template.format); + strb->defined = GL_FALSE; /* undefined contents now */ + /* Probably need dedicated flags for surface usage too: */ surface_usage = (PIPE_BUFFER_USAGE_GPU_READ | diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 44fa9fe9a4..fd77d0a95b 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -44,6 +44,7 @@ struct st_renderbuffer struct pipe_texture *texture; struct pipe_surface *surface; /* temporary view into texture */ enum pipe_format format; /** preferred format, or PIPE_FORMAT_NONE */ + GLboolean defined; /**< defined contents? */ struct st_texture_object *rtt; /**< GL render to texture's texture */ int rtt_level, rtt_face, rtt_slice; diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index fbaffd154f..8ceeeabcd3 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -47,10 +47,19 @@ #include "util/u_blit.h" +/** Check if we have a front color buffer and if it's been drawn to. */ static INLINE GLboolean is_front_buffer_dirty(struct st_context *st) { - return st->frontbuffer_status == FRONT_STATUS_DIRTY; + if (st->frontbuffer_status == FRONT_STATUS_DIRTY) { + return GL_TRUE; + } + else { + GLframebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; + } } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 6ffed56d9a..18adb35e87 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -45,6 +45,7 @@ struct blit_state; struct bitmap_cache; +/** XXX we'd like to get rid of these */ #define FRONT_STATUS_UNDEFINED 0 #define FRONT_STATUS_DIRTY 1 #define FRONT_STATUS_COPY_OF_BACK 2 @@ -111,7 +112,7 @@ struct st_context struct gl_fragment_program *fragment_program; } cb; - GLuint frontbuffer_status; /**< one of FRONT_STATUS_ */ + GLuint frontbuffer_status; /**< one of FRONT_STATUS_ (XXX to be removed) */ char vendor[100]; char renderer[100]; diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 07ccaa6aab..639373fff7 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -331,6 +331,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); *front_left = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front buffer, display the back buffer */ @@ -354,6 +360,12 @@ st_swapbuffers(struct st_framebuffer *stfb, st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); *front_right = strb->surface; } + /* mark back buffer contents as undefined */ + { + struct st_renderbuffer *back = + st_renderbuffer(fb->Attachment[BUFFER_BACK_RIGHT].Renderbuffer); + back->defined = GL_FALSE; + } } else { /* no front right buffer, display back right buffer (if exists) */ -- cgit v1.2.3 From 3f52a853f795d7432b181de81da6f0c4cf1cc202 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:48:46 -0600 Subject: st: when creating an on-demand front color buffer, init to back buffer image When we create a new front color buffer (user called glDrawBuffer(GL_FRONT)) initialize it to the contents of the back buffer. Any previous call to SwapBuffers() would have done that in effect, so make it reality. --- src/mesa/state_tracker/st_cb_fbo.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index fe9befaa2c..9ae4208a18 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -454,6 +454,31 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Copy back color buffer to front color buffer. + */ +static void +copy_back_to_front(struct st_context *st, + struct gl_framebuffer *fb, + gl_buffer_index frontIndex, + gl_buffer_index backIndex) + +{ + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + struct pipe_surface *surf_front, *surf_back; + + (void) st_get_framebuffer_surface(stfb, frontIndex, &surf_front); + (void) st_get_framebuffer_surface(stfb, backIndex, &surf_back); + + if (surf_front && surf_back) { + st->pipe->surface_copy(st->pipe, + surf_front, 0, 0, /* dest */ + surf_back, 0, 0, /* src */ + fb->Width, fb->Height); + } +} + + /** * Check if we're drawing into, or read from, a front color buffer. If the * front buffer is missing, create it now. @@ -493,7 +518,7 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, uint samples; if (0) - _mesa_debug(ctx, "Allocate new front buffer"); + _mesa_debug(ctx, "Allocate new front buffer\n"); /* get back renderbuffer info */ back = st_renderbuffer(fb->Attachment[backIndex].Renderbuffer); @@ -507,6 +532,11 @@ check_create_front_buffer(GLcontext *ctx, struct gl_framebuffer *fb, /* alloc texture/surface for new front buffer */ front->AllocStorage(ctx, front, front->InternalFormat, fb->Width, fb->Height); + + /* initialize the front color buffer contents by copying + * the back buffer. + */ + copy_back_to_front(ctx->st, fb, frontIndex, backIndex); } } } -- cgit v1.2.3 From 602833b107cdf3d70117dbd0970c7d574fb55f3b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 16:44:04 -0600 Subject: st: if st_swapbuffers() is called for single-buffered visual don't crash Furthermore, return pointer(s) to the front color buffer(s). --- src/mesa/state_tracker/st_framebuffer.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index 639373fff7..ef800291cc 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -297,7 +297,10 @@ st_notify_swapbuffers(struct st_framebuffer *stfb) * Swap the front/back color buffers. Exchange the front/back pointers * and update some derived state. * No need to call st_notify_swapbuffers() first. - * This is effectively a no-op for single-buffered framebuffers. + * + * For a single-buffered framebuffer, no swap occurs, but we still return + * the pointer(s) to the front color buffer(s). + * * \param front_left returns pointer to front-left renderbuffer after swap * \param front_right returns pointer to front-right renderbuffer after swap */ @@ -318,6 +321,21 @@ st_swapbuffers(struct st_framebuffer *stfb, NULL ); } + if (!fb->Visual.doubleBufferMode) { + /* single buffer mode - return pointers to front surfaces */ + if (front_left) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + *front_left = strb->surface; + } + if (front_right) { + struct st_renderbuffer *strb = + st_renderbuffer(fb->Attachment[BUFFER_FRONT_RIGHT].Renderbuffer); + *front_right = strb ? strb->surface : NULL; + } + return; + } + /* swap left buffers */ if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer && fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer) { -- cgit v1.2.3 From 63f01309801c5a900d8d7f5ccd63413e33ff9bff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:04:07 -0600 Subject: mesa: fix state validation bug for glCopyTex[Sub]Image() We need to make sure the framebuffer state is up to date to make sure we read pixels from the right buffer when doing a texture image copy. --- src/mesa/main/teximage.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 8c03c36c75..76b46d700b 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -51,6 +51,17 @@ #include "mtypes.h" +/** + * State changes which we care about for glCopyTex[Sub]Image() calls. + * In particular, we care about pixel transfer state and buffer state + * (such as glReadBuffer to make sure we read from the right renderbuffer). + */ +#define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \ + _NEW_BUFFERS | \ + _NEW_PIXEL) + + + /** * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE * elsewhere. @@ -3008,7 +3019,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -3073,7 +3084,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -3141,7 +3152,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 1, target, level)) @@ -3196,7 +3207,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 2, target, level)) @@ -3251,7 +3262,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 3, target, level)) -- cgit v1.2.3 From 0a56a4968786bd93d9117af2a0a3bda13ea71c4d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:17:34 -0600 Subject: st: create renderbuffer's pipe_surface in st_render_texture() Previously we created the pipe_surface during framebuffer validation. But if we did a glCopyTex[Sub]Image() before anything else we wouldn't yet have the surface. This fixes that. --- src/mesa/state_tracker/st_cb_fbo.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 1590f275e2..e003b6db5c 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -343,6 +343,7 @@ st_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { + struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb; struct gl_renderbuffer *rb; struct pipe_texture *pt = st_get_texobj_texture(att->Texture); @@ -365,6 +366,8 @@ st_render_texture(GLcontext *ctx, rb->AllocStorage = NULL; /* should not get called */ strb = st_renderbuffer(rb); + assert(strb->Base.RefCount > 0); + /* get the texture for the texture object */ stObj = st_texture_object(att->Texture); @@ -384,7 +387,14 @@ st_render_texture(GLcontext *ctx, pipe_surface_reference(&strb->surface, NULL); - /* the new surface will be created during framebuffer validation */ + /* new surface for rendering into the texture */ + strb->surface = screen->get_tex_surface(screen, + strb->texture, + strb->rtt_face, + strb->rtt_level, + strb->rtt_slice, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); init_renderbuffer_bits(strb, pt->format); -- cgit v1.2.3 From 62043b27575c378c027251316421e4699f461108 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:31:04 -0600 Subject: mesa: in glReadBufer() set _NEW_BUFFERS, not _NEW_PIXEL Since GL_READ_BUFFER is historically part of the gl_pixel_attrib group it made sense to signal changes with _NEW_PIXEL. But now with FBOs it's also part of the framebuffer state. Now _NEW_PIXEL strictly indicates pixels transfer state changes. This change avoids framebuffer state validation when any random bit of pixel-transfer state is set. DRI drivers updated too: don't check _NEW_COLOR when updating framebuffer state. I think that was just copied from the Xlib driver because we care about dither enable/disable state there. --- src/mesa/drivers/dri/intel/intel_buffers.c | 2 +- src/mesa/drivers/dri/r200/r200_state.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 2 +- src/mesa/drivers/dri/radeon/radeon_state.c | 2 +- src/mesa/drivers/x11/xm_dd.c | 3 ++- src/mesa/main/buffers.c | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index b86cafea24..4f4ea45b74 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -157,7 +157,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* Do this here, not core Mesa, since this function is called from * many places within the driver. */ - if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (ctx->NewState & _NEW_BUFFERS) { /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ _mesa_update_framebuffer(ctx); /* this updates the DrawBuffer's Width/Height if it's a FBO */ diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 28ba5f49bc..81ee1ed022 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2480,7 +2480,7 @@ void r200ValidateState( GLcontext *ctx ) r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint new_state = rmesa->NewGLState; - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { r200UpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index b96ba4ed94..07299f3b36 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2589,7 +2589,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _tnl_InvalidateState(ctx, new_state); _ae_invalidate_state(ctx, new_state); - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { r300UpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index b6561001e7..4432f85691 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -2255,7 +2255,7 @@ void radeonValidateState( GLcontext *ctx ) radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint new_state = rmesa->NewGLState; - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { radeonUpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 305df548fa..9a01465bdf 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -912,8 +912,9 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) /* * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect * renderbuffer span/clear funcs. + * Check _NEW_COLOR to detect dither enable/disable. */ - if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) { + if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) { XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); struct xmesa_renderbuffer *front_xrb, *back_xrb; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index c5f13345f0..d8b5f3b1f4 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -443,7 +443,7 @@ _mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex) fb->ColorReadBuffer = buffer; fb->_ColorReadBufferIndex = bufferIndex; - ctx->NewState |= _NEW_PIXEL; + ctx->NewState |= _NEW_BUFFERS; } -- cgit v1.2.3 From 27dbdb1684af42ce3e7962111fa0726cf7ba28d1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 4 May 2009 11:13:35 -0600 Subject: mesa: remove some unfinished/devel code --- src/mesa/shader/prog_optimize.c | 92 ----------------------------------------- 1 file changed, 92 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c index a02f5efa41..be903106a0 100644 --- a/src/mesa/shader/prog_optimize.c +++ b/src/mesa/shader/prog_optimize.c @@ -812,98 +812,6 @@ _mesa_reallocate_registers(struct gl_program *prog) } - - - - - - -#if 0 -static void -_mesa_find_temporary_live_intervals(struct gl_program *prog, - GLint firstInst[MAX_PROGRAM_TEMPS], - GLint lastInst[MAX_PROGRAM_TEMPS]) -{ - GLuint i; - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - firstInst[i] = lastInst[i] = -1; - } - - struct loop_info loopStack[MAX_LOOP_NESTING]; - GLuint loopStackDepth = 0; - GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; - GLuint i; - - /* - * Note: we'll return GL_FALSE below if we find relative indexing - * into the TEMP register file. We can't handle that yet. - * We also give up on subroutines for now. - */ - - if (dbg) { - _mesa_printf("Optimize: Begin find intervals\n"); - } - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ - intBegin[i] = intEnd[i] = -1; - } - - /* Scan instructions looking for temporary registers */ - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_BGNLOOP) { - loopStack[loopStackDepth].Start = i; - loopStack[loopStackDepth].End = inst->BranchTarget; - loopStackDepth++; - } - else if (inst->Opcode == OPCODE_ENDLOOP) { - loopStackDepth--; - } - else if (inst->Opcode == OPCODE_CAL) { - return GL_FALSE; - } - else { - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { - const GLuint index = inst->SrcReg[j].Index; - if (inst->SrcReg[j].RelAddr) - return GL_FALSE; - update_interval(intBegin, intEnd, index, i); - if (loopStackDepth > 0) { - /* extend temp register's interval to end of loop */ - GLuint loopEnd = loopStack[loopStackDepth - 1].End; - update_interval(intBegin, intEnd, index, loopEnd); - } - } - } - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - const GLuint index = inst->DstReg.Index; - if (inst->DstReg.RelAddr) - return GL_FALSE; - update_interval(intBegin, intEnd, index, i); - if (loopStackDepth > 0) { - /* extend temp register's interval to end of loop */ - GLuint loopEnd = loopStack[loopStackDepth - 1].End; - update_interval(intBegin, intEnd, index, loopEnd); - } - } - } - } - - - - -#endif - - - - - - - /** * Apply optimizations to the given program to eliminate unnecessary * instructions, temp regs, etc. -- cgit v1.2.3 From f95c0c06c0970d9a7700c7c8cea6396982b4b0dc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 4 May 2009 11:14:35 -0600 Subject: mesa: also print program params/constants when dumping shaders to disk --- src/mesa/shader/prog_print.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9967f2978d..e6f9a91069 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -941,6 +941,10 @@ _mesa_write_shader_to_file(const struct gl_shader *shader) fprintf(f, "/*\n"); _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE); fprintf(f, "*/\n"); + fprintf(f, "/* Parameters / constants */\n"); + fprintf(f, "/*\n"); + _mesa_fprint_parameter_list(f, shader->Program->Parameters); + fprintf(f, "*/\n"); } fclose(f); -- cgit v1.2.3 From 22b417b75ce0e6658a5d1e0e80cb6c3fdf631774 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 1 May 2009 18:20:42 +0100 Subject: mesa/main: set PREFER_DP4 to match position_invarient code This is a quick fix for z fighting in quake4 caused by the mismatch between vertex transformation here and in the position_invarient code. Full fix would be to make this driver-tunable and adjust both position_invarient and ffvertex_prog.c code to respect driver preferences. --- src/mesa/main/ffvertex_prog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 1ce5685af4..82e1c4af66 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -319,7 +319,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) * multiplications with DP4's or with MUL/MAD's? SSE works better * with the latter, drivers may differ. */ -#define PREFER_DP4 0 +#define PREFER_DP4 1 /* Use uregs to represent registers internally, translate to Mesa's -- cgit v1.2.3 From 113403ef51e2ec764db061aabf569d6f1a1a3ef0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 5 May 2009 12:12:28 +0100 Subject: mesa: more complete fix for transform_invarient glitches Add a new flag mvp_with_dp4 in the context, and use that to switch both ffvertex.c and programopt.c vertex transformation code to either DP4 or MUL/MAD implementations. --- src/mesa/main/context.c | 13 ++++ src/mesa/main/context.h | 4 ++ src/mesa/main/ffvertex_prog.c | 16 +++-- src/mesa/main/mtypes.h | 6 ++ src/mesa/shader/programopt.c | 119 +++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_context.c | 6 ++ 6 files changed, 153 insertions(+), 11 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 016284de9a..d780f91f04 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1522,4 +1522,17 @@ _mesa_Flush(void) } +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + /*@}*/ diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index ecc1cec779..5b57d88029 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -151,6 +151,10 @@ extern struct _glapi_table * _mesa_get_dispatch(GLcontext *ctx); +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ); + /** \name Miscellaneous */ /*@{*/ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 82e1c4af66..43325b1352 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -315,12 +315,6 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) */ #define DISASSEM 0 -/* Should be tunable by the driver - do we want to do matrix - * multiplications with DP4's or with MUL/MAD's? SSE works better - * with the latter, drivers may differ. - */ -#define PREFER_DP4 1 - /* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. @@ -348,6 +342,7 @@ struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; GLint max_inst; /** number of instructions allocated for program */ + GLboolean mvp_with_dp4; GLuint temp_in_use; GLuint temp_reserved; @@ -775,7 +770,7 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); @@ -881,7 +876,7 @@ static void build_hpos( struct tnl_program *p ) struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); @@ -1574,7 +1569,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); @@ -1708,6 +1703,7 @@ static void build_tnl_program( struct tnl_program *p ) static void create_new_program( const struct state_key *key, struct gl_vertex_program *program, + GLboolean mvp_with_dp4, GLuint max_temps) { struct tnl_program p; @@ -1721,6 +1717,7 @@ create_new_program( const struct state_key *key, p.transformed_normal = undef; p.identity = undef; p.temp_in_use = 0; + p.mvp_with_dp4 = mvp_with_dp4; if (max_temps >= sizeof(int) * 8) p.temp_reserved = 0; @@ -1776,6 +1773,7 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx) return NULL; create_new_program( &key, prog, + ctx->mvp_with_dp4, ctx->Const.VertexProgram.MaxTemps ); #if 0 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index cf71077728..587dc80146 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2980,6 +2980,12 @@ struct __GLcontextRec /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ecd98dc85c..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -45,8 +45,8 @@ * into a vertex program. * May be used to implement the position_invariant option. */ -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +static void +_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -113,6 +113,121 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) } +static void +_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + struct prog_instruction *newInst; + const GLuint origLen = vprog->Base.NumInstructions; + const GLuint newLen = origLen + 4; + GLuint hposTemp; + GLuint i; + + /* + * Setup state references for the modelview/projection matrix. + * XXX we should check if these state vars are already declared. + */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, + }; + GLint mvpRef[4]; + + for (i = 0; i < 4; i++) { + mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, + mvpState[i]); + } + + /* Alloc storage for new instructions */ + newInst = _mesa_alloc_instructions(newLen); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glProgramString(inserting position_invariant code)"); + return; + } + + /* TEMP hposTemp; */ + hposTemp = vprog->Base.NumTemporaries++; + + /* + * Generated instructions: + * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); + * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); + */ + _mesa_init_instructions(newInst, 4); + + newInst[0].Opcode = OPCODE_MUL; + newInst[0].DstReg.File = PROGRAM_TEMPORARY; + newInst[0].DstReg.Index = hposTemp; + newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[0].SrcReg[0].File = PROGRAM_INPUT; + newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; + newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[0].SrcReg[1].Index = mvpRef[0]; + newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; + + for (i = 1; i <= 2; i++) { + newInst[i].Opcode = OPCODE_MAD; + newInst[i].DstReg.File = PROGRAM_TEMPORARY; + newInst[i].DstReg.Index = hposTemp; + newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[i].SrcReg[0].File = PROGRAM_INPUT; + newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); + newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[i].SrcReg[1].Index = mvpRef[i]; + newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[i].SrcReg[2].Index = hposTemp; + newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; + } + + newInst[3].Opcode = OPCODE_MAD; + newInst[3].DstReg.File = PROGRAM_OUTPUT; + newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[3].SrcReg[0].File = PROGRAM_INPUT; + newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; + newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[3].SrcReg[1].Index = mvpRef[3]; + newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[3].SrcReg[2].Index = hposTemp; + newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + + /* Append original instructions after new instructions */ + _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); + + /* free old instructions */ + _mesa_free_instructions(vprog->Base.Instructions, origLen); + + /* install new instructions */ + vprog->Base.Instructions = newInst; + vprog->Base.NumInstructions = newLen; + vprog->Base.InputsRead |= VERT_BIT_POS; + vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); +} + + +void +_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + if (ctx->mvp_with_dp4) + _mesa_insert_mvp_dp4_code( ctx, vprog ); + else + _mesa_insert_mvp_mad_code( ctx, vprog ); +} + + + + + /** * Append extra instructions onto the given fragment program to implement diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92a630eff9..2a1f21c51c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -177,6 +177,12 @@ struct st_context *st_create_context(struct pipe_context *pipe, ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); + /* XXX: need a capability bit in gallium to query if the pipe + * driver prefers DP4 or MUL/MAD for vertex transformation. + */ + if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + return st_create_context_priv(ctx, pipe); } -- cgit v1.2.3 From c0d3761c167c2d952e92c46cf3a0e26461985ada Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:17:55 -0600 Subject: mesa: minor simplification in enable_texture(), updated comments --- src/mesa/main/enable.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index f432be183c..2e7baa48ff 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -222,14 +222,16 @@ get_texcoord_unit(GLcontext *ctx) /** * Helper function to enable or disable a texture target. + * \param bit one of the TEXTURE_x_BIT values + * \return GL_TRUE if state is changing or GL_FALSE if no change */ static GLboolean -enable_texture(GLcontext *ctx, GLboolean state, GLbitfield bit) +enable_texture(GLcontext *ctx, GLboolean state, GLbitfield texBit) { const GLuint curr = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; - const GLuint newenabled = (!state) - ? (texUnit->Enabled & ~bit) : (texUnit->Enabled | bit); + const GLbitfield newenabled = state + ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit); if (!ctx->DrawBuffer->Visual.rgbMode || texUnit->Enabled == newenabled) return GL_FALSE; -- cgit v1.2.3 From 01e16befd4809e3e93ee7855a4a5d7df9fe010d9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:21:20 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 32d55ba8d5..9664bd58bc 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,10 +560,10 @@ update_texture_state( GLcontext *ctx ) } } - if (!texUnit->_ReallyEnabled) { - /* If we get here it means the shader (or fixed-function state) - * is expecting a texture object, but there isn't one (or it's - * incomplete). Use the fallback texture. + if (fprog && !texUnit->_ReallyEnabled) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. */ struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; -- cgit v1.2.3 From a0edbfb28fb2e670c657d52190a7e8b1ccf4f46e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:29:04 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 9664bd58bc..5453331c67 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,14 +560,20 @@ update_texture_state( GLcontext *ctx ) } } - if (fprog && !texUnit->_ReallyEnabled) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); + if (!texUnit->_ReallyEnabled) { + if (fprog) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); + } + else { + /* fixed-function: texture unit is really disabled */ + continue; + } } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From 823815a48556940cc27867717658afda93733ce8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:30:30 -0600 Subject: Revert "mesa: only use fallback texture when using shaders, not fixed-function" This reverts commit a0edbfb28fb2e670c657d52190a7e8b1ccf4f46e. This patch didn't completely fix the problem. The next patch will. --- src/mesa/main/texstate.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 5453331c67..9664bd58bc 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,20 +560,14 @@ update_texture_state( GLcontext *ctx ) } } - if (!texUnit->_ReallyEnabled) { - if (fprog) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); - } - else { - /* fixed-function: texture unit is really disabled */ - continue; - } + if (fprog && !texUnit->_ReallyEnabled) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From 51325f44d1e7e62b47795a79f8038d10dc5bc30b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:29:04 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function (take two) The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. For fixed function, the texture unit is truly disabled/ignored. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 9664bd58bc..5453331c67 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,14 +560,20 @@ update_texture_state( GLcontext *ctx ) } } - if (fprog && !texUnit->_ReallyEnabled) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); + if (!texUnit->_ReallyEnabled) { + if (fprog) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); + } + else { + /* fixed-function: texture unit is really disabled */ + continue; + } } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From d277547dc69c9004097afdc2ca56a7aed85c6f54 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 5 May 2009 13:07:33 -0700 Subject: i965: Don't create constant buffers if they won't be used. Really, the creation and upload of constants should be in the same place, since they should only happen together, and a state flag should be triggered by them so that we don't thrash state around so much for just updating constants. But this still recovers openarena performance by another 19%, leaving us 16% behind Mesa 7.4 branch. --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f646ee7fc3..ad28c78f69 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -396,6 +396,14 @@ brw_update_wm_constant_surface( GLcontext *ctx, struct brw_surface_key key; struct intel_context *intel = &brw->intel; const int size = params->NumParameters * 4 * sizeof(GLfloat); + struct brw_fragment_program *fp = + (struct brw_fragment_program *) brw->fragment_program; + + if (!fp->use_const_buffer) { + dri_bo_unreference(const_buffer); + brw->wm.surf_bo[surf] = NULL; + return NULL; + } /* free old const buffer if too small */ if (const_buffer && const_buffer->size < size) { @@ -455,6 +463,8 @@ brw_update_vs_constant_surface( GLcontext *ctx, struct brw_surface_key key; struct intel_context *intel = &brw->intel; const int size = params->NumParameters * 4 * sizeof(GLfloat); + struct brw_vertex_program *vp = + (struct brw_vertex_program *) brw->vertex_program; assert(surf == 0); @@ -463,6 +473,11 @@ brw_update_vs_constant_surface( GLcontext *ctx, */ dri_bo_unreference(const_buffer); + if (!vp->use_const_buffer) { + brw->vs.surf_bo[surf] = NULL; + return NULL; + } + /* alloc new buffer */ const_buffer = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", size, 64); @@ -703,7 +718,8 @@ static void prepare_wm_surfaces(struct brw_context *brw ) brw_update_wm_constant_surface(ctx, surf, fp->const_buffer, fp->program.Base.Parameters); - brw->wm.nr_surfaces = surf + 1; + if (fp->const_buffer != NULL) + brw->wm.nr_surfaces = surf + 1; } /* Update surfaces for textures */ -- cgit v1.2.3 From 9490d86808300e5819941a40784e272c290e05ee Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 5 May 2009 14:05:54 -0700 Subject: i965: Disentangle VS constant surface state from WM surface state. Also, only create VS surface state if there's a VS constant buffer to be uploaded, and set the contents of the buffer at the same time as creation. --- src/mesa/drivers/dri/i965/Makefile | 1 + src/mesa/drivers/dri/i965/brw_curbe.c | 15 -- src/mesa/drivers/dri/i965/brw_misc_state.c | 5 +- src/mesa/drivers/dri/i965/brw_state.h | 20 ++ src/mesa/drivers/dri/i965/brw_state_upload.c | 3 +- src/mesa/drivers/dri/i965/brw_vs_surface_state.c | 226 +++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 171 +---------------- 7 files changed, 255 insertions(+), 186 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/brw_vs_surface_state.c (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 2934414d99..4913c25f74 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -69,6 +69,7 @@ DRIVER_SOURCES = \ brw_vs_constval.c \ brw_vs_emit.c \ brw_vs_state.c \ + brw_vs_surface_state.c \ brw_vtbl.c \ brw_wm.c \ brw_wm_debug.c \ diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 05a685af3d..7bd5021346 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -363,20 +363,6 @@ update_constant_buffer(struct brw_context *brw, } -/** Copy current vertex program's parameters into the constant buffer */ -static void -update_vertex_constant_buffer(struct brw_context *brw) -{ - struct brw_vertex_program *vp = - (struct brw_vertex_program *) brw->vertex_program; - if (0) { - printf("update VS constants in buffer %p vp = %p\n", vp->const_buffer, vp); - printf("program %u\n", vp->program.Base.Id); - } - if (vp->use_const_buffer) - update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer); -} - /** Copy current fragment program's parameters into the constant buffer */ static void @@ -398,7 +384,6 @@ static void emit_constant_buffer(struct brw_context *brw) struct intel_context *intel = &brw->intel; GLuint sz = brw->curbe.total_size; - update_vertex_constant_buffer(brw); update_fragment_constant_buffer(brw); BEGIN_BATCH(2, IGNORE_CLIPRECTS); diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 9bc5c35139..4784254bc7 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -118,7 +118,10 @@ static void upload_binding_table_pointers(struct brw_context *brw) BEGIN_BATCH(6, IGNORE_CLIPRECTS); OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2)); - OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */ + if (brw->vs.bind_bo != NULL) + OUT_RELOC(brw->vs.bind_bo, I915_GEM_DOMAIN_SAMPLER, 0, 0); /* vs */ + else + OUT_BATCH(0); OUT_BATCH(0); /* gs */ OUT_BATCH(0); /* clip */ OUT_BATCH(0); /* sf */ diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 7ea2fc113c..1171e61ad4 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -72,6 +72,7 @@ const struct brw_tracked_state brw_sf_vp; const struct brw_tracked_state brw_state_base_address; const struct brw_tracked_state brw_urb_fence; const struct brw_tracked_state brw_vertex_state; +const struct brw_tracked_state brw_vs_surfaces; const struct brw_tracked_state brw_vs_prog; const struct brw_tracked_state brw_vs_unit; const struct brw_tracked_state brw_wm_input_sizes; @@ -91,6 +92,20 @@ const struct brw_tracked_state brw_drawing_rect; const struct brw_tracked_state brw_indices; const struct brw_tracked_state brw_vertices; +/** + * Use same key for WM and VS surfaces. + */ +struct brw_surface_key { + GLenum target, depthmode; + dri_bo *bo; + GLint format, internal_format; + GLint first_level, last_level; + GLint width, height, depth; + GLint pitch, cpp; + uint32_t tiling; + GLuint offset; +}; + /*********************************************************************** * brw_state.c */ @@ -150,4 +165,9 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw, void brw_destroy_batch_cache( struct brw_context *brw ); void brw_clear_batch_cache_flush( struct brw_context *brw ); +/* brw_wm_surface_state.c */ +dri_bo * +brw_create_constant_surface( struct brw_context *brw, + struct brw_surface_key *key ); + #endif diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 2641bcb2aa..4c1ffe81c9 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -62,7 +62,8 @@ const struct brw_tracked_state *atoms[] = &brw_cc_vp, &brw_cc_unit, - &brw_wm_surfaces, /* must do before samplers */ + &brw_vs_surfaces, /* must do before unit */ + &brw_wm_surfaces, /* must do before samplers and unit */ &brw_wm_samplers, &brw_wm_unit, diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c new file mode 100644 index 0000000000..89f47522a1 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -0,0 +1,226 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "main/mtypes.h" +#include "main/texformat.h" +#include "main/texstore.h" +#include "shader/prog_parameter.h" + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" + +/* Creates a new VS constant buffer reflecting the current VS program's + * constants, if needed by the VS program. + * + * Otherwise, constants go through the CURBEs using the brw_constant_buffer + * state atom. + */ +static drm_intel_bo * +brw_vs_update_constant_buffer(struct brw_context *brw) +{ + struct intel_context *intel = &brw->intel; + struct brw_vertex_program *vp = + (struct brw_vertex_program *) brw->vertex_program; + const struct gl_program_parameter_list *params = vp->program.Base.Parameters; + const int size = params->NumParameters * 4 * sizeof(GLfloat); + drm_intel_bo *const_buffer; + + /* BRW_NEW_VERTEX_PROGRAM */ + if (!vp->use_const_buffer) + return NULL; + + const_buffer = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", + size, 64); + + /* _NEW_PROGRAM_CONSTANTS */ + dri_bo_subdata(const_buffer, 0, size, params->ParameterValues); + + return const_buffer; +} + +/** + * Update the surface state for a VS constant buffer. + * + * Sets brw->vs.surf_bo[surf] and brw->vp->const_buffer. + */ +static void +brw_update_vs_constant_surface( GLcontext *ctx, + GLuint surf) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_surface_key key; + struct brw_vertex_program *vp = + (struct brw_vertex_program *) brw->vertex_program; + const struct gl_program_parameter_list *params = vp->program.Base.Parameters; + + assert(surf == 0); + + /* If we're in this state update atom, we need to update VS constants, so + * free the old buffer and create a new one for the new contents. + */ + dri_bo_unreference(vp->const_buffer); + vp->const_buffer = brw_vs_update_constant_buffer(brw); + + /* If there's no constant buffer, then no surface BO is needed to point at + * it. + */ + if (vp->const_buffer == 0) { + drm_intel_bo_unreference(brw->vs.surf_bo[surf]); + brw->vs.surf_bo[surf] = NULL; + return; + } + + memset(&key, 0, sizeof(key)); + + key.format = MESA_FORMAT_RGBA_FLOAT32; + key.internal_format = GL_RGBA; + key.bo = vp->const_buffer; + key.depthmode = GL_NONE; + key.pitch = params->NumParameters; + key.width = params->NumParameters; + key.height = 1; + key.depth = 1; + key.cpp = 16; + + /* + printf("%s:\n", __FUNCTION__); + printf(" width %d height %d depth %d cpp %d pitch %d\n", + key.width, key.height, key.depth, key.cpp, key.pitch); + */ + + drm_intel_bo_unreference(brw->vs.surf_bo[surf]); + brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL); + if (brw->vs.surf_bo[surf] == NULL) { + brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key); + } +} + + +/** + * Constructs the binding table for the VS surface state. + */ +static dri_bo * +brw_vs_get_binding_table(struct brw_context *brw) +{ + dri_bo *bind_bo; + + bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + NULL); + + if (bind_bo == NULL) { + GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint); + uint32_t *data = malloc(data_size); + int i; + + for (i = 0; i < BRW_VS_MAX_SURF; i++) + if (brw->vs.surf_bo[i]) + data[i] = brw->vs.surf_bo[i]->offset; + else + data[i] = 0; + + bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, + NULL, 0, + brw->vs.surf_bo, BRW_VS_MAX_SURF, + data, data_size, + NULL, NULL); + + /* Emit binding table relocations to surface state */ + for (i = 0; i < BRW_VS_MAX_SURF; i++) { + if (brw->vs.surf_bo[i] != NULL) { + /* The presumed offsets were set in the data values for + * brw_upload_cache. + */ + drm_intel_bo_emit_reloc(bind_bo, i * 4, + brw->vs.surf_bo[i], 0, + I915_GEM_DOMAIN_INSTRUCTION, 0); + } + } + + free(data); + } + + return bind_bo; +} + +/** + * Vertex shader surfaces (constant buffer). + * + * This consumes the state updates for the constant buffer needing + * to be updated, and produces BRW_NEW_NR_VS_SURFACES for the VS unit and + * CACHE_NEW_SURF_BIND for the binding table upload. + */ +static void prepare_vs_surfaces(struct brw_context *brw ) +{ + GLcontext *ctx = &brw->intel.ctx; + int i; + int nr_surfaces = 0; + + brw_update_vs_constant_surface(ctx, SURF_INDEX_VERT_CONST_BUFFER); + + for (i = 0; i < BRW_VS_MAX_SURF; i++) { + if (brw->vs.surf_bo[i] != NULL) { + nr_surfaces = i + 1; + } + } + + if (brw->vs.nr_surfaces != nr_surfaces) { + brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES; + brw->vs.nr_surfaces = nr_surfaces; + } + + /* Note that we don't end up updating the bind_bo if we don't have a + * surface to be pointing at. This should be relatively harmless, as it + * just slightly increases our working set size. + */ + if (brw->vs.nr_surfaces != 0) { + dri_bo_unreference(brw->vs.bind_bo); + brw->vs.bind_bo = brw_vs_get_binding_table(brw); + } +} + +const struct brw_tracked_state brw_vs_surfaces = { + .dirty = { + .mesa = (_NEW_PROGRAM_CONSTANTS), + .brw = (BRW_NEW_VERTEX_PROGRAM), + .cache = 0 + }, + .prepare = prepare_vs_surfaces, +}; + + + diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index ad28c78f69..052bcf342c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -176,22 +176,6 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format, } } - -/** - * Use same key for WM and VS surfaces. - */ -struct brw_surface_key { - GLenum target, depthmode; - dri_bo *bo; - GLint format, internal_format; - GLint first_level, last_level; - GLint width, height, depth; - GLint pitch, cpp; - uint32_t tiling; - GLuint offset; -}; - - static void brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling) { @@ -337,7 +321,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) * Create the constant buffer surface. Vertex/fragment shader constants will be * read from this buffer with Data Port Read instructions/messages. */ -static dri_bo * +dri_bo * brw_create_constant_surface( struct brw_context *brw, struct brw_surface_key *key ) { @@ -449,71 +433,6 @@ brw_update_wm_constant_surface( GLcontext *ctx, } -/** - * Update the surface state for a VS constant buffer. - * The constant buffer will be (re)allocated here if needed. - */ -static dri_bo * -brw_update_vs_constant_surface( GLcontext *ctx, - GLuint surf, - dri_bo *const_buffer, - const struct gl_program_parameter_list *params) -{ - struct brw_context *brw = brw_context(ctx); - struct brw_surface_key key; - struct intel_context *intel = &brw->intel; - const int size = params->NumParameters * 4 * sizeof(GLfloat); - struct brw_vertex_program *vp = - (struct brw_vertex_program *) brw->vertex_program; - - assert(surf == 0); - - /* We always create a new VS constant buffer so that several can be - * in flight at a time. Free the old one first... - */ - dri_bo_unreference(const_buffer); - - if (!vp->use_const_buffer) { - brw->vs.surf_bo[surf] = NULL; - return NULL; - } - - /* alloc new buffer */ - const_buffer = - drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer", size, 64); - - memset(&key, 0, sizeof(key)); - - key.format = MESA_FORMAT_RGBA_FLOAT32; - key.internal_format = GL_RGBA; - key.bo = const_buffer; - key.depthmode = GL_NONE; - key.pitch = params->NumParameters; - key.width = params->NumParameters; - key.height = 1; - key.depth = 1; - key.cpp = 16; - - /* - printf("%s:\n", __FUNCTION__); - printf(" width %d height %d depth %d cpp %d pitch %d\n", - key.width, key.height, key.depth, key.cpp, key.pitch); - */ - - dri_bo_unreference(brw->vs.surf_bo[surf]); - brw->vs.surf_bo[surf] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, key.bo ? 1 : 0, - NULL); - if (brw->vs.surf_bo[surf] == NULL) { - brw->vs.surf_bo[surf] = brw_create_constant_surface(brw, &key); - } - - return const_buffer; -} - - /** * Sets up a surface state structure to point at the given region. * While it is only used for the front/back buffer currently, it should be @@ -753,92 +672,6 @@ static void prepare_wm_surfaces(struct brw_context *brw ) brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES; } - -/** - * Constructs the binding table for the VS surface state. - */ -static dri_bo * -brw_vs_get_binding_table(struct brw_context *brw) -{ - dri_bo *bind_bo; - - assert(brw->vs.nr_surfaces <= BRW_VS_MAX_SURF); - - bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, brw->vs.nr_surfaces, - NULL); - - if (bind_bo == NULL) { - GLuint data_size = brw->vs.nr_surfaces * sizeof(GLuint); - uint32_t *data = malloc(data_size); - int i; - - for (i = 0; i < brw->vs.nr_surfaces; i++) - if (brw->vs.surf_bo[i]) - data[i] = brw->vs.surf_bo[i]->offset; - else - data[i] = 0; - - bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, - NULL, 0, - brw->vs.surf_bo, brw->vs.nr_surfaces, - data, data_size, - NULL, NULL); - - /* Emit binding table relocations to surface state */ - for (i = 0; i < BRW_VS_MAX_SURF; i++) { - if (brw->vs.surf_bo[i] != NULL) { - dri_bo_emit_reloc(bind_bo, - I915_GEM_DOMAIN_INSTRUCTION, 0, - 0, - i * sizeof(GLuint), - brw->vs.surf_bo[i]); - } - } - - free(data); - } - - return bind_bo; -} - - -/** - * Vertex shader surfaces (constant buffer). - */ -static void prepare_vs_surfaces(struct brw_context *brw ) -{ - GLcontext *ctx = &brw->intel.ctx; - - /* Update surface / buffer for vertex shader constant buffer */ - { - const GLuint surf = SURF_INDEX_VERT_CONST_BUFFER; - struct brw_vertex_program *vp = - (struct brw_vertex_program *) brw->vertex_program; - vp->const_buffer = - brw_update_vs_constant_surface(ctx, surf, vp->const_buffer, - vp->program.Base.Parameters); - - brw->vs.nr_surfaces = 1; - } - - dri_bo_unreference(brw->vs.bind_bo); - brw->vs.bind_bo = brw_vs_get_binding_table(brw); - - if (1) - brw->state.dirty.brw |= BRW_NEW_NR_VS_SURFACES; -} - - -static void -prepare_surfaces(struct brw_context *brw) -{ - prepare_wm_surfaces(brw); - prepare_vs_surfaces(brw); -} - - const struct brw_tracked_state brw_wm_surfaces = { .dirty = { .mesa = (_NEW_COLOR | @@ -849,7 +682,7 @@ const struct brw_tracked_state brw_wm_surfaces = { .brw = (BRW_NEW_CONTEXT), .cache = 0 }, - .prepare = prepare_surfaces, + .prepare = prepare_wm_surfaces, }; -- cgit v1.2.3 From 71fb9d62ece0177183efd5bb955d1f3292cb4376 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 5 May 2009 17:16:15 -0700 Subject: i965: Split WM constant buffer update from other WM surfaces. This can avoid re-uploading constant data when it isn't necessary, and is a step towards not updating other surfaces just because constants change. It also brings the upload of the constant buffer next to the creation. This brings openarena performance up another 4%, to 91% of the Mesa 7.4 branch. --- src/mesa/drivers/dri/i965/brw_context.h | 1 + src/mesa/drivers/dri/i965/brw_curbe.c | 52 --------- src/mesa/drivers/dri/i965/brw_state.h | 1 + src/mesa/drivers/dri/i965/brw_state_upload.c | 1 + src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 130 ++++++++++++++++------- 5 files changed, 95 insertions(+), 90 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 838e718d0d..873fc8ffff 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -131,6 +131,7 @@ struct brw_context; #define BRW_NEW_WM_INPUT_DIMENSIONS 0x100 #define BRW_NEW_INPUT_VARYING 0x200 #define BRW_NEW_PSP 0x800 +#define BRW_NEW_WM_SURFACES 0x1000 #define BRW_NEW_FENCE 0x2000 #define BRW_NEW_INDICES 0x4000 #define BRW_NEW_VERTICES 0x8000 diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 7bd5021346..a1a6c53d0e 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -329,63 +329,11 @@ static void prepare_constant_buffer(struct brw_context *brw) */ } - -/** - * Copy Mesa program parameters into given constant buffer. - */ -static void -update_constant_buffer(struct brw_context *brw, - const struct gl_program_parameter_list *params, - dri_bo *const_buffer) -{ - struct intel_context *intel = &brw->intel; - const int size = params->NumParameters * 4 * sizeof(GLfloat); - - /* copy Mesa program constants into the buffer */ - if (const_buffer && size > 0) { - - assert(const_buffer); - assert(const_buffer->size >= size); - - if (intel->intelScreen->kernel_exec_fencing) { - drm_intel_gem_bo_map_gtt(const_buffer); - memcpy(const_buffer->virtual, params->ParameterValues, size); - drm_intel_gem_bo_unmap_gtt(const_buffer); - } - else { - dri_bo_subdata(const_buffer, 0, size, params->ParameterValues); - } - - if (0) { - _mesa_print_parameter_list(params); - } - } -} - - - -/** Copy current fragment program's parameters into the constant buffer */ -static void -update_fragment_constant_buffer(struct brw_context *brw) -{ - struct brw_fragment_program *fp = - (struct brw_fragment_program *) brw->fragment_program; - if (0) { - printf("update WM constants in buffer %p\n", fp->const_buffer); - printf("program %u\n", fp->program.Base.Id); - } - if (fp->use_const_buffer) - update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer); -} - - static void emit_constant_buffer(struct brw_context *brw) { struct intel_context *intel = &brw->intel; GLuint sz = brw->curbe.total_size; - update_fragment_constant_buffer(brw); - BEGIN_BATCH(2, IGNORE_CLIPRECTS); if (sz == 0) { OUT_BATCH((CMD_CONST_BUFFER << 16) | (2 - 2)); diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 1171e61ad4..bf9f6cae55 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -78,6 +78,7 @@ const struct brw_tracked_state brw_vs_unit; const struct brw_tracked_state brw_wm_input_sizes; const struct brw_tracked_state brw_wm_prog; const struct brw_tracked_state brw_wm_samplers; +const struct brw_tracked_state brw_wm_constant_surface; const struct brw_tracked_state brw_wm_surfaces; const struct brw_tracked_state brw_wm_unit; diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 4c1ffe81c9..c6dfea4743 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -63,6 +63,7 @@ const struct brw_tracked_state *atoms[] = &brw_cc_unit, &brw_vs_surfaces, /* must do before unit */ + &brw_wm_constant_surface, /* must do before wm surfaces/bind bo */ &brw_wm_surfaces, /* must do before samplers and unit */ &brw_wm_samplers, diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 052bcf342c..53ce39cfe2 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -365,47 +365,70 @@ brw_create_constant_surface( struct brw_context *brw, return bo; } +/* Creates a new WM constant buffer reflecting the current fragment program's + * constants, if needed by the fragment program. + * + * Otherwise, constants go through the CURBEs using the brw_constant_buffer + * state atom. + */ +static drm_intel_bo * +brw_wm_update_constant_buffer(struct brw_context *brw) +{ + struct intel_context *intel = &brw->intel; + struct brw_fragment_program *fp = + (struct brw_fragment_program *) brw->fragment_program; + const struct gl_program_parameter_list *params = fp->program.Base.Parameters; + const int size = params->NumParameters * 4 * sizeof(GLfloat); + drm_intel_bo *const_buffer; + + /* BRW_NEW_FRAGMENT_PROGRAM */ + if (!fp->use_const_buffer) + return NULL; + + const_buffer = drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer", + size, 64); + + /* _NEW_PROGRAM_CONSTANTS */ + dri_bo_subdata(const_buffer, 0, size, params->ParameterValues); + + return const_buffer; +} /** * Update the surface state for a WM constant buffer. * The constant buffer will be (re)allocated here if needed. */ -static dri_bo * +static void brw_update_wm_constant_surface( GLcontext *ctx, - GLuint surf, - dri_bo *const_buffer, - const struct gl_program_parameter_list *params) + GLuint surf) { struct brw_context *brw = brw_context(ctx); struct brw_surface_key key; - struct intel_context *intel = &brw->intel; - const int size = params->NumParameters * 4 * sizeof(GLfloat); struct brw_fragment_program *fp = (struct brw_fragment_program *) brw->fragment_program; + const struct gl_program_parameter_list *params = + fp->program.Base.Parameters; - if (!fp->use_const_buffer) { - dri_bo_unreference(const_buffer); - brw->wm.surf_bo[surf] = NULL; - return NULL; - } - - /* free old const buffer if too small */ - if (const_buffer && const_buffer->size < size) { - dri_bo_unreference(const_buffer); - const_buffer = NULL; - } + /* If we're in this state update atom, we need to update WM constants, so + * free the old buffer and create a new one for the new contents. + */ + dri_bo_unreference(fp->const_buffer); + fp->const_buffer = brw_wm_update_constant_buffer(brw); - /* alloc new buffer if needed */ - if (!const_buffer) { - const_buffer = - drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer", size, 64); + /* If there's no constant buffer, then no surface BO is needed to point at + * it. + */ + if (fp->const_buffer == 0) { + drm_intel_bo_unreference(brw->wm.surf_bo[surf]); + brw->wm.surf_bo[surf] = NULL; + return; } memset(&key, 0, sizeof(key)); key.format = MESA_FORMAT_RGBA_FLOAT32; key.internal_format = GL_RGBA; - key.bo = const_buffer; + key.bo = fp->const_buffer; key.depthmode = GL_NONE; key.pitch = params->NumParameters; key.width = params->NumParameters; @@ -428,10 +451,51 @@ brw_update_wm_constant_surface( GLcontext *ctx, if (brw->wm.surf_bo[surf] == NULL) { brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key); } + brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; +} - return const_buffer; +/** + * Updates surface / buffer for fragment shader constant buffer, if + * one is required. + * + * This consumes the state updates for the constant buffer, and produces + * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for + * inclusion in the binding table. + */ +static void prepare_wm_constant_surface(struct brw_context *brw ) +{ + GLcontext *ctx = &brw->intel.ctx; + struct brw_fragment_program *fp = + (struct brw_fragment_program *) brw->fragment_program; + GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER; + + drm_intel_bo_unreference(fp->const_buffer); + fp->const_buffer = brw_wm_update_constant_buffer(brw); + + /* If there's no constant buffer, then no surface BO is needed to point at + * it. + */ + if (fp->const_buffer == 0) { + if (brw->wm.surf_bo[surf] != NULL) { + drm_intel_bo_unreference(brw->wm.surf_bo[surf]); + brw->wm.surf_bo[surf] = NULL; + brw->state.dirty.brw |= BRW_NEW_WM_SURFACES; + } + return; + } + + brw_update_wm_constant_surface(ctx, surf); } +const struct brw_tracked_state brw_wm_constant_surface = { + .dirty = { + .mesa = (_NEW_PROGRAM_CONSTANTS), + .brw = (BRW_NEW_FRAGMENT_PROGRAM), + .cache = 0 + }, + .prepare = prepare_wm_constant_surface, +}; + /** * Sets up a surface state structure to point at the given region. @@ -628,18 +692,8 @@ static void prepare_wm_surfaces(struct brw_context *brw ) old_nr_surfaces = brw->wm.nr_surfaces; brw->wm.nr_surfaces = MAX_DRAW_BUFFERS; - /* Update surface / buffer for fragment shader constant buffer */ - { - const GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER; - struct brw_fragment_program *fp = - (struct brw_fragment_program *) brw->fragment_program; - fp->const_buffer = - brw_update_wm_constant_surface(ctx, surf, fp->const_buffer, - fp->program.Base.Parameters); - - if (fp->const_buffer != NULL) - brw->wm.nr_surfaces = surf + 1; - } + if (brw->wm.surf_bo[SURF_INDEX_FRAG_CONST_BUFFER] != NULL) + brw->wm.nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1; /* Update surfaces for textures */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { @@ -677,9 +731,9 @@ const struct brw_tracked_state brw_wm_surfaces = { .mesa = (_NEW_COLOR | _NEW_TEXTURE | _NEW_BUFFERS | - _NEW_PROGRAM | - _NEW_PROGRAM_CONSTANTS), - .brw = (BRW_NEW_CONTEXT), + _NEW_PROGRAM), + .brw = (BRW_NEW_CONTEXT | + BRW_NEW_WM_SURFACES), .cache = 0 }, .prepare = prepare_wm_surfaces, -- cgit v1.2.3 From 9b678af7967bb88044c5fe437e050472fa03eaca Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 08:45:55 -0600 Subject: mesa: be smarter about allocating vert/frag program constants Try to re-use constants/literals more often to make best use of the constant buffer space. See bug 21354. --- src/mesa/shader/arbprogparse.c | 101 +++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 25 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index c7a031067e..36267c336f 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -563,6 +563,7 @@ struct var_cache * we take up with our state tokens or constants. Note that * this is _not_ the same as the number of param registers * we eventually use */ + GLuint swizzle; /**< swizzle to access this variable */ struct var_cache *next; }; @@ -581,6 +582,7 @@ var_cache_create (struct var_cache **va) (**va).param_binding_begin = ~0; (**va).param_binding_length = ~0; (**va).alias_binding = NULL; + (**va).swizzle = SWIZZLE_XYZW; (**va).next = NULL; } } @@ -872,15 +874,16 @@ parse_signed_float (const GLubyte ** inst, struct arb_program *Program) * This picks out a constant value from the parsed array. The constant vector is r * returned in the *values array, which should be of length 4. * - * \param values - The 4 component vector with the constant value in it + * \param values - return the vector constant values. + * \param size - returns the number elements in valuesOut [1..4] */ static GLvoid -parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Program, - GLboolean use) +parse_constant(const GLubyte ** inst, GLfloat *values, GLint *size, + struct arb_program *Program, + GLboolean use) { GLuint components, i; - switch (*(*inst)++) { case CONSTANT_SCALAR: if (use == GL_TRUE) { @@ -893,7 +896,7 @@ parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Prog values[1] = values[2] = values[3] = parse_signed_float (inst, Program); } - + *size = 1; break; case CONSTANT_VECTOR: values[0] = values[1] = values[2] = 0; @@ -902,7 +905,12 @@ parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Prog for (i = 0; i < components; i++) { values[i] = parse_signed_float (inst, Program); } + *size = 4; break; + default: + _mesa_problem(NULL, "unexpected case in parse_constant()"); + values[0] = 0.0F; + *size = 0; } } @@ -1816,7 +1824,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, GLint idx; GLuint err = 0; gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; - GLfloat const_values[4]; GLubyte token = *(*inst)++; @@ -1908,18 +1915,31 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, case PARAM_CONSTANT: /* parsing something like {1.0, 2.0, 3.0, 4.0} */ - parse_constant (inst, const_values, Program, use); - idx = _mesa_add_named_constant(Program->Base.Parameters, - (char *) param_var->name, - const_values, 4); - if (param_var->param_binding_begin == ~0U) - param_var->param_binding_begin = idx; - param_var->param_binding_type = PROGRAM_STATE_VAR; - /* Note: when we reference this parameter in an instruction later, - * we'll check if it's really a constant/immediate and set the - * instruction register type appropriately. - */ - param_var->param_binding_length++; + { + GLfloat const_values[4]; + GLint size; + parse_constant(inst, const_values, &size, Program, use); + if (param_var->name[0] == ' ') { + /* this is an unnamed constant */ + idx = _mesa_add_unnamed_constant(Program->Base.Parameters, + const_values, size, + ¶m_var->swizzle); + } + else { + /* named parameter/constant */ + idx = _mesa_add_named_constant(Program->Base.Parameters, + (char *) param_var->name, + const_values, size); + } + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_type = PROGRAM_STATE_VAR; + /* Note: when we reference this parameter in an instruction later, + * we'll check if it's really a constant/immediate and set the + * instruction register type appropriately. + */ + param_var->param_binding_length++; + } break; default: @@ -2428,6 +2448,9 @@ parse_swizzle_mask(const GLubyte ** inst, GLubyte *swizzle, GLint len) return; } } + + if (len == 1) + swizzle[1] = swizzle[2] = swizzle[3] = swizzle[0]; } @@ -2482,7 +2505,7 @@ static GLuint parse_src_reg (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, struct arb_program *Program, - gl_register_file * File, GLint * Index, + gl_register_file * File, GLint * Index, GLuint *swizzle, GLboolean *IsRelOffset ) { struct var_cache *src; @@ -2491,6 +2514,8 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, *IsRelOffset = 0; + *swizzle = SWIZZLE_XYZW; /* default */ + /* And the binding for the src */ switch (*(*inst)++) { case REGISTER_ATTRIB: @@ -2546,6 +2571,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, } *Index = src->param_binding_begin + offset; + *swizzle = src->swizzle; break; case ARRAY_INDEX_RELATIVE: @@ -2568,6 +2594,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, /* And store it properly */ *Index = src->param_binding_begin + rel_off; *IsRelOffset = 1; + *swizzle = src->swizzle; } break; } @@ -2579,6 +2606,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, *File = (gl_register_file) src->param_binding_type; *Index = src->param_binding_begin; + *swizzle = src->swizzle; break; } break; @@ -2647,6 +2675,21 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, } +static GLuint +swizzle_swizzle(GLuint baseSwizzle, const GLubyte swizzle[4]) +{ + GLuint i, swz, s[4]; + for (i = 0; i < 4; i++) { + GLuint c = swizzle[i]; + if (c <= SWIZZLE_W) + s[i] = GET_SWZ(baseSwizzle, c); + else + s[i] = c; + } + swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]); + return swz; +} + /** * Parse vertex/fragment program vector source register. */ @@ -2661,12 +2704,14 @@ parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, GLubyte negateMask; GLubyte swizzle[4]; GLboolean isRelOffset; + GLuint baseSwizzle; /* Grab the sign */ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; /* And the src reg */ - if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) + if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle, + &isRelOffset)) return 1; /* finally, the swizzle */ @@ -2674,7 +2719,7 @@ parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst, reg->File = file; reg->Index = index; - reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); + reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle); reg->Negate = negateMask; reg->RelAddr = isRelOffset; return 0; @@ -2695,12 +2740,14 @@ parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, GLubyte negateMask; GLubyte swizzle[4]; GLboolean isRelOffset; + GLuint baseSwizzle; /* Grab the sign */ negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE; /* And the src reg */ - if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset)) + if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle, + &isRelOffset)) return 1; /* finally, the swizzle */ @@ -2708,7 +2755,7 @@ parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst, reg->File = file; reg->Index = index; - reg->Swizzle = (swizzle[0] << 0); + reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle); reg->Negate = negateMask; reg->RelAddr = isRelOffset; return 0; @@ -3019,8 +3066,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, GLubyte negateMask; gl_register_file file; GLint index; + GLuint baseSwizzle; - if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel)) + if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, + &baseSwizzle, &rel)) return 1; parse_extended_swizzle_mask(inst, swizzle, &negateMask); fp->SrcReg[0].File = file; @@ -3360,11 +3409,13 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, GLboolean relAddr; gl_register_file file; GLint index; + GLuint baseSwizzle; if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) return 1; - if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr)) + if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, + &baseSwizzle, &relAddr)) return 1; parse_extended_swizzle_mask (inst, swizzle, &negateMask); vp->SrcReg[0].File = file; -- cgit v1.2.3 From 4cb87840ff7c99654a89f45c6a5a2a026a587a2f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 6 May 2009 07:58:40 -0700 Subject: i965: Remove _NEW_PROGRAM from brw_wm_surfaces setup dependencies. This was a leftover from the brw_wm_constant_buffer change. --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 53ce39cfe2..f2d9541e51 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -730,8 +730,7 @@ const struct brw_tracked_state brw_wm_surfaces = { .dirty = { .mesa = (_NEW_COLOR | _NEW_TEXTURE | - _NEW_BUFFERS | - _NEW_PROGRAM), + _NEW_BUFFERS), .brw = (BRW_NEW_CONTEXT | BRW_NEW_WM_SURFACES), .cache = 0 -- cgit v1.2.3 From f831d2d41b5551abcf61f19880bc96779c5efd51 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 6 May 2009 10:51:58 -0700 Subject: i965: Remove the forced lack of caching for renderbuffer surface state. This snuck in with the multi-draw-buffers commit, and is a major penalty to performance. It doesn't appear to be required, as the only dependency the surface BO has is on the state key (and if there's some other dependency, it should just be in the key). This brings openarena performance up to almost 2% faster than Mesa 7.4. --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f2d9541e51..c49a5f6b4e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -505,7 +505,7 @@ const struct brw_tracked_state brw_wm_constant_surface = { static void brw_update_renderbuffer_surface(struct brw_context *brw, struct gl_renderbuffer *rb, - unsigned int unit, GLboolean cached) + unsigned int unit) { GLcontext *ctx = &brw->intel.ctx; dri_bo *region_bo = NULL; @@ -565,13 +565,11 @@ brw_update_renderbuffer_surface(struct brw_context *brw, ctx->Color.BlendEnabled); dri_bo_unreference(brw->wm.surf_bo[unit]); - brw->wm.surf_bo[unit] = NULL; - if (cached) - brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, - BRW_SS_SURFACE, - &key, sizeof(key), - ®ion_bo, 1, - NULL); + brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, + BRW_SS_SURFACE, + &key, sizeof(key), + ®ion_bo, 1, + NULL); if (brw->wm.surf_bo[unit] == NULL) { struct brw_surface_state surf; @@ -682,11 +680,10 @@ static void prepare_wm_surfaces(struct brw_context *brw ) for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { brw_update_renderbuffer_surface(brw, ctx->DrawBuffer->_ColorDrawBuffers[i], - i, - GL_FALSE); + i); } } else { - brw_update_renderbuffer_surface(brw, NULL, 0, GL_TRUE); + brw_update_renderbuffer_surface(brw, NULL, 0); } old_nr_surfaces = brw->wm.nr_surfaces; -- cgit v1.2.3 From a13df193c23f9202ade6f16643e3ef529cff772b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:23:28 -0600 Subject: mesa: use elementBuf local var instead of ctx->Array.ElementArrayBufferObj Makes no real difference, but more consistant. --- src/mesa/main/api_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 42d1e579e0..1986cbecbb 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -72,7 +72,7 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, if (map) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); + elementBuf); } return max; -- cgit v1.2.3 From 88af3f8783452dcf50a9e2e82076f52b2044f643 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:27:38 -0600 Subject: mesa: new comments, minor reformatting --- src/mesa/main/api_validate.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 1986cbecbb..dfe754dee5 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -44,10 +44,8 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, if (elementBuf->Name) { /* elements are in a user-defined buffer object. need to map it */ - map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_READ_ONLY, - elementBuf); + map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY, elementBuf); /* Actual address is the sum of pointers */ indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); } @@ -70,14 +68,16 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, } if (map) { - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - elementBuf); + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf); } return max; } + +/** + * Check if OK to render by examining framebuffer status and vertex arrays. + */ static GLboolean check_valid_to_render(GLcontext *ctx, char *function) { @@ -105,6 +105,12 @@ check_valid_to_render(GLcontext *ctx, char *function) return GL_TRUE; } + +/** + * Error checking for glDrawElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ GLboolean _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, @@ -184,6 +190,12 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_TRUE; } + +/** + * Error checking for glDrawRangeElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ GLboolean _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, GLuint start, GLuint end, @@ -265,6 +277,7 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /** * Called from the tnl module to error check the function parameters and * verify that we really can draw something. + * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_DrawArrays(GLcontext *ctx, -- cgit v1.2.3 From bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:37:10 -0600 Subject: mesa: code consolidation in glDraw[Range]Elements() validation --- src/mesa/main/api_validate.c | 48 ++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index dfe754dee5..ad150eea80 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -30,6 +30,26 @@ #include "state.h" + +/** + * \return number of bytes in array [count] of type. + */ +static GLsizei +index_bytes(GLenum type, GLsizei count) +{ + if (type == GL_UNSIGNED_INT) { + return count * sizeof(GLuint); + } + else if (type == GL_UNSIGNED_BYTE) { + return count * sizeof(GLubyte); + } + else { + ASSERT(type == GL_UNSIGNED_SHORT); + return count * sizeof(GLushort); + } +} + + /** * Find the max index in the given element/index buffer */ @@ -146,7 +166,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - GLuint indexBytes; if (!ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, @@ -154,19 +173,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_FALSE; } - if (type == GL_UNSIGNED_INT) { - indexBytes = count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - indexBytes = count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - indexBytes = count * sizeof(GLushort); - } - /* make sure count doesn't go outside buffer bounds */ - if (indexBytes > (GLuint) ctx->Array.ElementArrayBufferObj->Size) { + if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); return GL_FALSE; } @@ -236,21 +244,9 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - GLuint indexBytes; - - if (type == GL_UNSIGNED_INT) { - indexBytes = count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - indexBytes = count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - indexBytes = count * sizeof(GLushort); - } /* make sure count doesn't go outside buffer bounds */ - if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { + if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); return GL_FALSE; } -- cgit v1.2.3 From 58544a28ad561d7d9e16deb048443c2d2b5c12d8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:38:11 -0600 Subject: mesa: remove unnecessary buffer size check --- src/mesa/main/api_validate.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index ad150eea80..27049486ee 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -166,13 +166,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - - if (!ctx->Array.ElementArrayBufferObj->Size) { - _mesa_warning(ctx, - "glDrawElements called with empty array elements buffer"); - return GL_FALSE; - } - /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); @@ -244,7 +237,6 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); -- cgit v1.2.3 From 156a79f5bd7b3e79f219adf4619ec449a7c0ed1c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 6 May 2009 13:58:57 -0700 Subject: intel: Unmap buffers if needed at DeleteBuffer time. This fixes a crash in glean's pbo test, which tripped over the assert when a context was destroyed while a buffer was still mapped (Mesa doesn't call UnmapBuffer in that case). Regression in c6bde8873fbda6d8467600b7491d8543c75b0509 --- src/mesa/drivers/dri/intel/intel_buffer_objects.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c index c849e4869e..f6b0d769c6 100644 --- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c @@ -35,6 +35,9 @@ #include "intel_batchbuffer.h" #include "intel_regions.h" +static GLboolean +intel_bufferobj_unmap(GLcontext * ctx, + GLenum target, struct gl_buffer_object *obj); /** Allocates a new dri_bo to store the data for the buffer object. */ static void @@ -100,7 +103,13 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - assert(!obj->Pointer); /* Mesa should have unmapped it */ + + /* Buffer objects are automatically unmapped when deleting according + * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy + * (though it does if you call glDeleteBuffers) + */ + if (obj->Pointer) + intel_bufferobj_unmap(ctx, 0, obj); if (intel_obj->region) { intel_bufferobj_release_region(intel, intel_obj); -- cgit v1.2.3 From 3d048e57504c63999aeaaf5a65e8e493e6a67ff7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 6 May 2009 21:44:13 -0700 Subject: i965: Remove bad constant buffer constant-reg-already-loaded optimization. Thanks to branching, the state of c->current_const[i].index at the point of emitting constant loads for this instruction may not match the actual constant currently loaded in the reg at runtime. Fixes a regression in my GLSL program for idr's class since b58b3a786aa38dcc9d72144c2cc691151e46e3d5. --- src/mesa/drivers/dri/i965/brw_wm_glsl.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 39ea95f6fc..cc2c6ab189 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -407,23 +407,21 @@ static void fetch_constants(struct brw_wm_compile *c, if (src->File == PROGRAM_STATE_VAR || src->File == PROGRAM_CONSTANT || src->File == PROGRAM_UNIFORM) { - if (c->current_const[i].index != src->Index) { - c->current_const[i].index = src->Index; + c->current_const[i].index = src->Index; #if 0 - printf(" fetch const[%d] for arg %d into reg %d\n", - src->Index, i, c->current_const[i].reg.nr); + printf(" fetch const[%d] for arg %d into reg %d\n", + src->Index, i, c->current_const[i].reg.nr); #endif - /* need to fetch the constant now */ - brw_dp_READ_4(p, - c->current_const[i].reg, /* writeback dest */ - 1, /* msg_reg */ - src->RelAddr, /* relative indexing? */ - 16 * src->Index, /* byte offset */ - SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */ - ); - } + /* need to fetch the constant now */ + brw_dp_READ_4(p, + c->current_const[i].reg, /* writeback dest */ + 1, /* msg_reg */ + src->RelAddr, /* relative indexing? */ + 16 * src->Index, /* byte offset */ + SURF_INDEX_FRAG_CONST_BUFFER/* binding table index */ + ); } } } -- cgit v1.2.3 From cc7170464493453ec8213decd21df95121b236e2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 09:36:21 -0600 Subject: mesa: unmap buffer objects during context tear-down --- src/mesa/main/shared.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 193ac8970c..ae8dd2a836 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -190,6 +190,10 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData) { struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data; GLcontext *ctx = (GLcontext *) userData; + if (bufObj->Pointer) { + ctx->Driver.UnmapBuffer(ctx, 0, bufObj); + bufObj->Pointer = NULL; + } ctx->Driver.DeleteBuffer(ctx, bufObj); } -- cgit v1.2.3 From 6a3004b9ae58dafd1ce995df78b0f3183827a59d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 09:43:15 -0600 Subject: swrast: fix span clipping bug If a horizontal span of pixels was located at x < 0 we could sometimes read/write outside of renderbuffer bounds. --- src/mesa/swrast/s_span.c | 84 ++++++++++++++++++++++++++++++++++++------------ src/mesa/swrast/s_span.h | 9 ++++-- 2 files changed, 71 insertions(+), 22 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index cfff82b051..fa8ca1d0e2 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.5 * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -188,10 +189,10 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) const GLfloat dv1dx = span->attrStepX[attr][1]; const GLfloat dv2dx = span->attrStepX[attr][2]; const GLfloat dv3dx = span->attrStepX[attr][3]; - GLfloat v0 = span->attrStart[attr][0]; - GLfloat v1 = span->attrStart[attr][1]; - GLfloat v2 = span->attrStart[attr][2]; - GLfloat v3 = span->attrStart[attr][3]; + GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx; + GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx; + GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx; + GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx; GLuint k; for (k = 0; k < span->end; k++) { const GLfloat invW = 1.0f / w; @@ -521,10 +522,10 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) const GLfloat drdx = span->attrStepX[attr][2]; const GLfloat dqdx = span->attrStepX[attr][3]; const GLfloat dqdy = span->attrStepY[attr][3]; - GLfloat s = span->attrStart[attr][0]; - GLfloat t = span->attrStart[attr][1]; - GLfloat r = span->attrStart[attr][2]; - GLfloat q = span->attrStart[attr][3]; + GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; + GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; + GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx; + GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; if (obj) { const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; @@ -546,7 +547,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -587,7 +588,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -660,8 +661,8 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) } } - w = span->attrStart[FRAG_ATTRIB_WPOS][3]; dw = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dw; for (i = 0; i < span->end; i++) { wpos[i][2] = (GLfloat) span->array->z[i] * zScale; wpos[i][3] = w; @@ -726,6 +727,8 @@ clip_span( GLcontext *ctx, SWspan *span ) const GLint ymin = ctx->DrawBuffer->_Ymin; const GLint ymax = ctx->DrawBuffer->_Ymax; + span->leftClip = 0; + if (span->arrayMask & SPAN_XY) { /* arrays of x/y pixel coords */ const GLint *x = span->array->x; @@ -753,7 +756,7 @@ clip_span( GLcontext *ctx, SWspan *span ) /* horizontal span of pixels */ const GLint x = span->x; const GLint y = span->y; - const GLint n = span->end; + GLint n = span->end; /* Trivial rejection tests */ if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { @@ -761,18 +764,44 @@ clip_span( GLcontext *ctx, SWspan *span ) return GL_FALSE; /* all pixels clipped */ } + /* Clip to right */ + if (x + n > xmax) { + ASSERT(x < xmax); + n = span->end = xmax - x; + } + /* Clip to the left */ if (x < xmin) { + const GLint leftClip = xmin - x; + GLuint i; + + ASSERT(leftClip > 0); ASSERT(x + n > xmin); + + /* Clip 'leftClip' pixels from the left side. + * The span->leftClip field will be applied when we interpolate + * fragment attributes. + * For arrays of values, shift them left. + */ + for (i = 0; i < FRAG_ATTRIB_MAX; i++) { + if (span->arrayAttribs & (1 << i)) { + /* shift array elements left by 'leftClip' */ + _mesa_memcpy(span->array->attribs[i], + span->array->attribs[i] + leftClip, + (n - leftClip) * 4 * sizeof(GLfloat)); + } + } + + span->leftClip = leftClip; + span->x = xmin; + span->end -= leftClip; span->writeAll = GL_FALSE; - _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); } - /* Clip to right */ - if (x + n > xmax) { - ASSERT(x < xmax); - span->end = xmax - x; - } + ASSERT(span->x >= xmin); + ASSERT(span->x + span->end <= xmax); + ASSERT(span->y >= ymin); + ASSERT(span->y < ymax); return GL_TRUE; /* some pixels visible */ } @@ -818,6 +847,12 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) } } + if (!(span->arrayMask & SPAN_MASK)) { + /* post-clip sanity check */ + assert(span->x >= 0); + assert(span->y >= 0); + } + /* Depth bounds test */ if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { if (!_swrast_depth_bounds_test(ctx, span)) { @@ -1284,6 +1319,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) #ifdef DEBUG /* Make sure all fragments are within window bounds */ if (span->arrayMask & SPAN_XY) { + /* array of pixel locations */ GLuint i; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { @@ -1321,6 +1357,14 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); + if ((span->arrayMask & SPAN_XY) == 0) { + if (span->x < fb->_Xmin || span->x + span->end > fb->_Xmax || + span->y < fb->_Ymin || span->y >= fb->_Ymax) { + printf("Bad span clipping at %d, %d\n", span->x, span->y); + return; + } + } + if (ctx->Stencil._Enabled) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index c4b47df58f..0eabae20e0 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.5 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -106,6 +107,9 @@ typedef struct sw_span /** Number of fragments in the span */ GLuint end; + /** for clipping left edge of spans */ + GLuint leftClip; + /** This flag indicates that mask[] array is effectively filled with ones */ GLboolean writeAll; @@ -165,6 +169,7 @@ do { \ (S).arrayMask = 0x0; \ (S).arrayAttribs = 0x0; \ (S).end = 0; \ + (S).leftClip = 0; \ (S).facing = 0; \ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ } while (0) -- cgit v1.2.3 From f56893ea173454ed5367eafb038fa4905f9ebce3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 08:16:42 -0600 Subject: i965: relAddr local var (to make debug/test a little easier) --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 3fdc48583b..0a3debb101 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -714,10 +714,11 @@ get_constant(struct brw_vs_compile *c, struct brw_compile *p = &c->func; struct brw_reg const_reg; struct brw_reg const2_reg; + const GLboolean relAddr = src->RelAddr; assert(argIndex < 3); - if (c->current_const[argIndex].index != src->Index || src->RelAddr) { + if (c->current_const[argIndex].index != src->Index || relAddr) { struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; c->current_const[argIndex].index = src->Index; @@ -730,13 +731,13 @@ get_constant(struct brw_vs_compile *c, brw_dp_READ_4_vs(p, c->current_const[argIndex].reg,/* writeback dest */ 0, /* oword */ - src->RelAddr, /* relative indexing? */ + relAddr, /* relative indexing? */ addrReg, /* address register */ 16 * src->Index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ ); - if (src->RelAddr) { + if (relAddr) { /* second read */ const2_reg = get_tmp(c); @@ -747,7 +748,7 @@ get_constant(struct brw_vs_compile *c, brw_dp_READ_4_vs(p, const2_reg, /* writeback dest */ 1, /* oword */ - src->RelAddr, /* relative indexing? */ + relAddr, /* relative indexing? */ addrReg, /* address register */ 16 * src->Index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER @@ -757,7 +758,7 @@ get_constant(struct brw_vs_compile *c, const_reg = c->current_const[argIndex].reg; - if (src->RelAddr) { + if (relAddr) { /* merge the two Owords into the constant register */ /* const_reg[7..4] = const2_reg[7..4] */ brw_MOV(p, -- cgit v1.2.3 From 134ac52decf020e6ffb2da8d641cdb3cda9ac0f2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 4 May 2009 18:22:19 -0600 Subject: tnl: replace 0x3f with CILP_FRUSTUM_BITS --- src/mesa/tnl/t_vb_cliptmp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index 788fe329ed..e1643c2735 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -127,7 +127,7 @@ TAG(clip_line)( GLcontext *ctx, GLuint v0, GLuint v1, GLubyte mask ) GLuint p; const GLuint v0_orig = v0; - if (mask & 0x3f) { + if (mask & CLIP_FRUSTUM_BITS) { LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); @@ -199,7 +199,7 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask ) ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ - if (mask & 0x3f) { + if (mask & CLIP_FRUSTUM_BITS) { POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); @@ -250,7 +250,7 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3, ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ - if (mask & 0x3f) { + if (mask & CLIP_FRUSTUM_BITS) { POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); -- cgit v1.2.3 From 424507953ca9d41e0dbfcc0399f50315b5671776 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 11:11:25 -0600 Subject: mesa: reformatting, updated comments, const-correctness --- src/mesa/math/m_vector.c | 84 ++++++++++++++++++++++-------------------------- src/mesa/math/m_vector.h | 25 +++++++------- 2 files changed, 50 insertions(+), 59 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c index c5e2fd1de1..dd631376d0 100644 --- a/src/mesa/math/m_vector.c +++ b/src/mesa/math/m_vector.c @@ -1,4 +1,3 @@ - /* * Mesa 3-D graphics library * Version: 3.5 @@ -37,11 +36,12 @@ -/* +/** * Given a vector [count][4] of floats, set all the [][elt] values * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). */ -void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) +void +_mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) { static const GLubyte elem_bits[4] = { VEC_DIRTY_0, @@ -54,12 +54,13 @@ void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; GLuint i; - for (i = 0 ; i < count ; i++) + for (i = 0; i < count; i++) data[i][elt] = v; vec->flags &= ~elem_bits[elt]; } + static const GLubyte size_bits[5] = { 0, VEC_SIZE_1, @@ -69,40 +70,34 @@ static const GLubyte size_bits[5] = { }; - -/* +/** * Initialize GLvector objects. - * Input: v - the vector object to initialize. - * flags - bitwise-OR of VEC_* flags - * storage - pointer to storage for the vector's data + * \param v the vector object to initialize. + * \param flags bitwise-OR of VEC_* flags + * \param storage pointer to storage for the vector's data */ - - -void _mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) +void +_mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) { v->stride = 4 * sizeof(GLfloat); v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ v->data = storage; v->start = (GLfloat *) storage; v->count = 0; - v->flags = size_bits[4] | flags ; + v->flags = size_bits[4] | flags; } - - -/* +/** * Initialize GLvector objects and allocate storage. - * Input: v - the vector object - * sz - unused???? - * flags - bitwise-OR of VEC_* flags - * count - number of elements to allocate in vector - * alignment - desired memory alignment for the data (in bytes) + * \param v the vector object + * \param flags bitwise-OR of VEC_* flags + * \param count number of elements to allocate in vector + * \param alignment desired memory alignment for the data (in bytes) */ - - -void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, - GLuint alignment ) +void +_mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, + GLuint alignment ) { v->stride = 4 * sizeof(GLfloat); v->size = 2; @@ -110,20 +105,17 @@ void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, v->start = (GLfloat *) v->storage; v->data = (GLfloat (*)[4]) v->storage; v->count = 0; - v->flags = size_bits[4] | flags | VEC_MALLOC ; + v->flags = size_bits[4] | flags | VEC_MALLOC; } - - -/* +/** * Vector deallocation. Free whatever memory is pointed to by the * vector's storage field if the VEC_MALLOC flag is set. * DO NOT free the GLvector object itself, though. */ - - -void _mesa_vector4f_free( GLvector4f *v ) +void +_mesa_vector4f_free( GLvector4f *v ) { if (v->flags & VEC_MALLOC) { ALIGN_FREE( v->storage ); @@ -135,13 +127,15 @@ void _mesa_vector4f_free( GLvector4f *v ) } -/* +/** * For debugging */ -void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) +void +_mesa_vector4f_print( const GLvector4f *v, const GLubyte *cullmask, + GLboolean culling ) { - GLfloat c[4] = { 0, 0, 0, 1 }; - const char *templates[5] = { + static const GLfloat c[4] = { 0, 0, 0, 1 }; + static const char *templates[5] = { "%d:\t0, 0, 0, 1\n", "%d:\t%f, 0, 0, 1\n", "%d:\t%f, %f, 0, 1\n", @@ -154,30 +148,32 @@ void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) GLuint j, i = 0, count; _mesa_printf("data-start\n"); - for ( ; d != v->start ; STRIDE_F(d, v->stride), i++) + for (; d != v->start; STRIDE_F(d, v->stride), i++) _mesa_printf(t, i, d[0], d[1], d[2], d[3]); _mesa_printf("start-count(%u)\n", v->count); count = i + v->count; if (culling) { - for ( ; i < count ; STRIDE_F(d, v->stride), i++) + for (; i < count; STRIDE_F(d, v->stride), i++) if (cullmask[i]) _mesa_printf(t, i, d[0], d[1], d[2], d[3]); } else { - for ( ; i < count ; STRIDE_F(d, v->stride), i++) + for (; i < count; STRIDE_F(d, v->stride), i++) _mesa_printf(t, i, d[0], d[1], d[2], d[3]); } - for (j = v->size ; j < 4; j++) { + for (j = v->size; j < 4; j++) { if ((v->flags & (1<data ; - i < count && d[j] == c[j] ; - i++, STRIDE_F(d, v->stride)) {}; + for (i = 0, d = (GLfloat *) v->data; + i < count && d[j] == c[j]; + i++, STRIDE_F(d, v->stride)) { + /* no-op */ + } if (i == count) _mesa_printf(" --> ok\n"); @@ -186,5 +182,3 @@ void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) } } } - - diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h index 647388ac7d..9112a2b5d5 100644 --- a/src/mesa/math/m_vector.h +++ b/src/mesa/math/m_vector.h @@ -31,7 +31,6 @@ #define _M_VECTOR_H_ #include "main/glheader.h" -#include "main/mtypes.h" /* hack for GLchan */ #define VEC_DIRTY_0 0x1 @@ -50,7 +49,8 @@ -/* Wrap all the information about vectors up in a struct. Has +/** + * Wrap all the information about vectors up in a struct. Has * additional fields compared to the other vectors to help us track of * different vertex sizes, and whether we need to clean columns out * because they contain non-(0,0,0,1) values. @@ -60,13 +60,13 @@ * the transformation routines. */ typedef struct { - GLfloat (*data)[4]; /* may be malloc'd or point to client data */ - GLfloat *start; /* points somewhere inside of */ - GLuint count; /* size of the vector (in elements) */ - GLuint stride; /* stride from one element to the next (in bytes) */ - GLuint size; /* 2-4 for vertices and 1-4 for texcoords */ - GLuint flags; /* which columns are dirty */ - void *storage; /* self-allocated storage */ + GLfloat (*data)[4]; /**< may be malloc'd or point to client data */ + GLfloat *start; /**< points somewhere inside of */ + GLuint count; /**< size of the vector (in elements) */ + GLuint stride; /**< stride from one element to the next (in bytes) */ + GLuint size; /**< 2-4 for vertices and 1-4 for texcoords */ + GLuint flags; /**< which columns are dirty */ + void *storage; /**< self-allocated storage */ } GLvector4f; @@ -75,14 +75,11 @@ extern void _mesa_vector4f_init( GLvector4f *v, GLuint flags, extern void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, GLuint alignment ); extern void _mesa_vector4f_free( GLvector4f *v ); -extern void _mesa_vector4f_print( GLvector4f *v, GLubyte *, GLboolean ); +extern void _mesa_vector4f_print( const GLvector4f *v, const GLubyte *, GLboolean ); extern void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt ); - - - -/* +/** * Given vector , return a pointer (cast to to the -th element. * * End up doing a lot of slow imuls if not careful. -- cgit v1.2.3 From ad32489987f3f65d37aee76083f466d674ada0c5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:45:24 -0600 Subject: tnl: added some clip debug/print code (disabled) --- src/mesa/tnl/t_vb_cliptmp.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/tnl/t_vb_cliptmp.h b/src/mesa/tnl/t_vb_cliptmp.h index e1643c2735..61b0a89554 100644 --- a/src/mesa/tnl/t_vb_cliptmp.h +++ b/src/mesa/tnl/t_vb_cliptmp.h @@ -227,6 +227,25 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask ) } } + if (0) { + /* print pre/post-clip vertex coords */ + GLuint i, j; + _mesa_printf("pre clip\n"); + for (i = 0; i < 3; i++) { + j = outlist[i]; + _mesa_printf(" %u: %u: %f, %f, %f, %f\n", + i, j, + coord[j][0], coord[j][1], coord[j][2], coord[j][3]); + } + _mesa_printf("post clip\n"); + for (i = 0; i < n; i++) { + j = inlist[i]; + _mesa_printf(" %u: %u: %f, %f, %f, %f\n", + i, j, + coord[j][0], coord[j][1], coord[j][2], coord[j][3]); + } + } + tnl->Driver.Render.ClippedPolygon( ctx, inlist, n ); } -- cgit v1.2.3 From 74bec42b45910e2ff6bf1a8cc0eeb2bc5c705767 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:01:47 -0600 Subject: mesa: limit number of error raised by invalid GL_TEXTURE_MAX_ANISOTROPY_EXT --- src/mesa/main/texparam.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index e60ab6aa12..2195a334d3 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -469,8 +469,10 @@ set_tex_parameterf(GLcontext *ctx, return GL_TRUE; } else { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); + static GLuint count = 0; + if (count++ < 10) + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); } return GL_FALSE; -- cgit v1.2.3 From 2369f14245222a9c073846baa1bb03e23aa37c15 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:51:56 -0600 Subject: mesa: in vbo split code, map buffers read-only, not write-only And use GL_ELEMENT_ARRAY_BUFFER where appropriate. --- src/mesa/vbo/vbo_split_copy.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 5fb66d3318..4fc0e36156 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -389,8 +389,8 @@ static void replay_init( struct copy_context *copy ) if (vbo->Name && !vbo->Pointer) ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, - GL_WRITE_ONLY, /* XXX */ + GL_ARRAY_BUFFER, + GL_READ_ONLY, vbo); copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer, @@ -406,8 +406,8 @@ static void replay_init( struct copy_context *copy ) */ if (copy->ib->obj->Name && !copy->ib->obj->Pointer) ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, /* XXX */ - GL_WRITE_ONLY, /* XXX */ + GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY, copy->ib->obj); srcptr = (const GLubyte *)ADD_POINTERS(copy->ib->obj->Pointer, copy->ib->ptr); @@ -509,14 +509,14 @@ static void replay_finish( struct copy_context *copy ) struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj; if (vbo->Name && vbo->Pointer) - ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, vbo); + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo); } /* Unmap index buffer: */ if (copy->ib->obj->Name && copy->ib->obj->Pointer) { ctx->Driver.UnmapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, /* XXX */ + GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj); } } -- cgit v1.2.3 From 87ba2285fe11dfe068798e5f8ea8e089a5d8b28b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:56:26 -0600 Subject: mesa: add GL_DOUBLE case in _mesa_sizeof_type() --- src/mesa/main/image.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index ddae456fa1..ea76ed04e4 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -181,6 +181,8 @@ _mesa_sizeof_type( GLenum type ) return sizeof(GLint); case GL_FLOAT: return sizeof(GLfloat); + case GL_DOUBLE: + return sizeof(GLdouble); case GL_HALF_FLOAT_ARB: return sizeof(GLhalfARB); default: -- cgit v1.2.3 From 3acdab82cba03ea2a0dfaa3d7d5d940f1e94a374 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 10:36:33 -0600 Subject: mesa: vbo code reformatting, clean-up, comments --- src/mesa/vbo/vbo_split_copy.c | 95 +++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 43 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 4fc0e36156..44b748dad7 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -41,7 +41,8 @@ #define ELT_TABLE_SIZE 16 -/* Used for vertex-level splitting of indexed buffers. Note that +/** + * Used for vertex-level splitting of indexed buffers. Note that * non-indexed primitives may be converted to indexed in some cases * (eg loops, fans) in order to use this splitting path. */ @@ -73,23 +74,21 @@ struct copy_context { GLuint *translated_elt_buf; const GLuint *srcelt; - /* A baby hash table to avoid re-emitting (some) duplicate + /** A baby hash table to avoid re-emitting (some) duplicate * vertices when splitting indexed primitives. */ struct { GLuint in; GLuint out; } vert_cache[ELT_TABLE_SIZE]; - GLuint vertex_size; GLubyte *dstbuf; - GLubyte *dstptr; /* dstptr == dstbuf + dstelt_max * vertsize */ - GLuint dstbuf_size; /* in vertices */ - GLuint dstbuf_nr; /* count of emitted vertices, also the - * largest value in dstelt. Our - * MaxIndex. - */ + GLubyte *dstptr; /**< dstptr == dstbuf + dstelt_max * vertsize */ + GLuint dstbuf_size; /**< in vertices */ + GLuint dstbuf_nr; /**< count of emitted vertices, also the largest value + * in dstelt. Our MaxIndex. + */ GLuint *dstelt; GLuint dstelt_nr; @@ -123,11 +122,13 @@ static GLuint attr_size( const struct gl_client_array *array ) } -/* Starts returning true slightly before the buffer fills, to ensure +/** + * Starts returning true slightly before the buffer fills, to ensure * that there is sufficient room for any remaining vertices to finish * off the prim: */ -static GLboolean check_flush( struct copy_context *copy ) +static GLboolean +check_flush( struct copy_context *copy ) { GLenum mode = copy->dstprim[copy->dstprim_nr].mode; @@ -145,7 +146,9 @@ static GLboolean check_flush( struct copy_context *copy ) return GL_FALSE; } -static void flush( struct copy_context *copy ) + +static void +flush( struct copy_context *copy ) { GLuint i; @@ -175,8 +178,11 @@ static void flush( struct copy_context *copy ) } - -static void begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag ) +/** + * Called at begin of each primitive during replay. + */ +static void +begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag ) { struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; @@ -187,10 +193,12 @@ static void begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag } -/* Use a hashtable to attempt to identify recently-emitted vertices +/** + * Use a hashtable to attempt to identify recently-emitted vertices * and avoid re-emitting them. */ -static GLuint elt(struct copy_context *copy, GLuint elt_idx) +static GLuint +elt(struct copy_context *copy, GLuint elt_idx) { GLuint elt = copy->srcelt[elt_idx]; GLuint slot = elt & (ELT_TABLE_SIZE-1); @@ -222,7 +230,6 @@ static GLuint elt(struct copy_context *copy, GLuint elt_idx) _mesa_printf("%x ", f[j]); _mesa_printf("\n"); } - } copy->vert_cache[slot].in = elt; @@ -230,9 +237,8 @@ static GLuint elt(struct copy_context *copy, GLuint elt_idx) copy->dstptr += copy->vertex_size; assert(csr == copy->dstptr); - assert(copy->dstptr == (copy->dstbuf + - copy->dstbuf_nr * - copy->vertex_size)); + assert(copy->dstptr == (copy->dstbuf + + copy->dstbuf_nr * copy->vertex_size)); } /* else */ /* _mesa_printf(" --> reuse vertex\n"); */ @@ -242,7 +248,12 @@ static GLuint elt(struct copy_context *copy, GLuint elt_idx) return check_flush(copy); } -static void end( struct copy_context *copy, GLboolean end_flag ) + +/** + * Called at end of each primitive during replay. + */ +static void +end( struct copy_context *copy, GLboolean end_flag ) { struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; @@ -257,8 +268,8 @@ static void end( struct copy_context *copy, GLboolean end_flag ) } - -static void replay_elts( struct copy_context *copy ) +static void +replay_elts( struct copy_context *copy ) { GLuint i, j, k; GLboolean split; @@ -362,7 +373,8 @@ static void replay_elts( struct copy_context *copy ) } -static void replay_init( struct copy_context *copy ) +static void +replay_init( struct copy_context *copy ) { GLcontext *ctx = copy->ctx; GLuint i; @@ -388,10 +400,7 @@ static void replay_init( struct copy_context *copy ) copy->vertex_size += attr_size(copy->array[i]); if (vbo->Name && !vbo->Pointer) - ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER, - GL_READ_ONLY, - vbo); + ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY, vbo); copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer, copy->array[i]->Ptr); @@ -405,12 +414,11 @@ static void replay_init( struct copy_context *copy ) * do it internally. */ if (copy->ib->obj->Name && !copy->ib->obj->Pointer) - ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER, - GL_READ_ONLY, + ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY, copy->ib->obj); - srcptr = (const GLubyte *)ADD_POINTERS(copy->ib->obj->Pointer, copy->ib->ptr); + srcptr = (const GLubyte *) ADD_POINTERS(copy->ib->obj->Pointer, + copy->ib->ptr); switch (copy->ib->type) { case GL_UNSIGNED_BYTE: @@ -434,7 +442,6 @@ static void replay_init( struct copy_context *copy ) copy->srcelt = (const GLuint *)srcptr; break; } - /* Figure out the maximum allowed vertex buffer size: */ @@ -449,8 +456,7 @@ static void replay_init( struct copy_context *copy ) * * XXX: This should be a VBO! */ - copy->dstbuf = _mesa_malloc(copy->dstbuf_size * - copy->vertex_size); + copy->dstbuf = _mesa_malloc(copy->dstbuf_size * copy->vertex_size); copy->dstptr = copy->dstbuf; /* Setup new vertex arrays to point into the output buffer: @@ -492,7 +498,11 @@ static void replay_init( struct copy_context *copy ) } -static void replay_finish( struct copy_context *copy ) +/** + * Free up everything allocated during split/replay. + */ +static void +replay_finish( struct copy_context *copy ) { GLcontext *ctx = copy->ctx; GLuint i; @@ -502,12 +512,11 @@ static void replay_finish( struct copy_context *copy ) _mesa_free(copy->translated_elt_buf); _mesa_free(copy->dstbuf); _mesa_free(copy->dstelt); - + /* Unmap VBO's */ for (i = 0; i < copy->nr_varying; i++) { struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj; - if (vbo->Name && vbo->Pointer) ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo); } @@ -515,12 +524,14 @@ static void replay_finish( struct copy_context *copy ) /* Unmap index buffer: */ if (copy->ib->obj->Name && copy->ib->obj->Pointer) { - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER, - copy->ib->obj); + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj); } } + +/** + * Split VBO into smaller pieces, draw the pieces. + */ void vbo_split_copy( GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, @@ -546,13 +557,11 @@ void vbo_split_copy( GLcontext *ctx, copy.draw = draw; copy.limits = limits; - /* Clear the vertex cache: */ for (i = 0; i < ELT_TABLE_SIZE; i++) copy.vert_cache[i].in = ~0; - replay_init(©); replay_elts(©); replay_finish(©); -- cgit v1.2.3 From 7e3bd457e8cf106391f4418d910b8267b4b0de2c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 10:54:34 -0600 Subject: mesa: use _mesa_sizeof_type() in vbo split code --- src/mesa/vbo/vbo_split_copy.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 44b748dad7..56a9fafac4 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -31,6 +31,7 @@ #include "main/glheader.h" #include "main/imports.h" +#include "main/image.h" #include "main/macros.h" #include "main/enums.h" #include "main/mtypes.h" @@ -101,24 +102,9 @@ struct copy_context { }; -static GLuint type_size( GLenum type ) -{ - switch(type) { - case GL_BYTE: return sizeof(GLbyte); - case GL_UNSIGNED_BYTE: return sizeof(GLubyte); - case GL_SHORT: return sizeof(GLshort); - case GL_UNSIGNED_SHORT: return sizeof(GLushort); - case GL_INT: return sizeof(GLint); - case GL_UNSIGNED_INT: return sizeof(GLuint); - case GL_FLOAT: return sizeof(GLfloat); - case GL_DOUBLE: return sizeof(GLdouble); - default: return 0; - } -} - static GLuint attr_size( const struct gl_client_array *array ) { - return array->Size * type_size(array->Type); + return array->Size * _mesa_sizeof_type(array->Type); } -- cgit v1.2.3 From b102c1d8f9ea359879e6c1c4fd8c80c00d21cad5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:48:21 -0600 Subject: mesa: fix/add comments --- src/mesa/main/mtypes.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 587dc80146..bdb1081ca8 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1542,9 +1542,8 @@ struct gl_client_array GLboolean Enabled; /**< Enabled flag is a boolean */ GLboolean Normalized; /**< GL_ARB_vertex_program */ - /**< GL_ARB_vertex_buffer_object */ - struct gl_buffer_object *BufferObj; - GLuint _MaxElement; + struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ + GLuint _MaxElement; /**< max element index into array buffer */ }; -- cgit v1.2.3 From a6c8e900af981e011e51268a2724e5ff4a3ff1eb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:56:15 -0600 Subject: mesa: use local var to make code a bit more concise --- src/mesa/main/state.c | 73 ++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index f18fc8f683..47e1aaa728 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -69,17 +69,18 @@ update_separate_specular(GLcontext *ctx) static void update_arrays( GLcontext *ctx ) { + const struct gl_array_object *arrayObj = ctx->Array.ArrayObj; GLuint i, min; /* find min of _MaxElement values for all enabled arrays */ /* 0 */ if (ctx->VertexProgram._Current - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; + && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { + min = arrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; } - else if (ctx->Array.ArrayObj->Vertex.Enabled) { - min = ctx->Array.ArrayObj->Vertex._MaxElement; + else if (arrayObj->Vertex.Enabled) { + min = arrayObj->Vertex._MaxElement; } else { /* can't draw anything without vertex positions! */ @@ -88,86 +89,86 @@ update_arrays( GLcontext *ctx ) /* 1 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); } /* no conventional vertex weight array */ /* 2 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); } - else if (ctx->Array.ArrayObj->Normal.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Normal._MaxElement); + else if (arrayObj->Normal.Enabled) { + min = MIN2(min, arrayObj->Normal._MaxElement); } /* 3 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); } - else if (ctx->Array.ArrayObj->Color.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Color._MaxElement); + else if (arrayObj->Color.Enabled) { + min = MIN2(min, arrayObj->Color._MaxElement); } /* 4 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); } - else if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->SecondaryColor._MaxElement); + else if (arrayObj->SecondaryColor.Enabled) { + min = MIN2(min, arrayObj->SecondaryColor._MaxElement); } /* 5 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); } - else if (ctx->Array.ArrayObj->FogCoord.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->FogCoord._MaxElement); + else if (arrayObj->FogCoord.Enabled) { + min = MIN2(min, arrayObj->FogCoord._MaxElement); } /* 6 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); } - else if (ctx->Array.ArrayObj->Index.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Index._MaxElement); + else if (arrayObj->Index.Enabled) { + min = MIN2(min, arrayObj->Index._MaxElement); } /* 7 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); } /* 8..15 */ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); + && arrayObj->VertexAttrib[i].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); } else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits - && ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); + && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { + min = MIN2(min, arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); } } /* 16..31 */ if (ctx->VertexProgram._Current) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { - if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); + if (arrayObj->VertexAttrib[i].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); } } } - if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->EdgeFlag._MaxElement); + if (arrayObj->EdgeFlag.Enabled) { + min = MIN2(min, arrayObj->EdgeFlag._MaxElement); } /* _MaxElement is one past the last legal array element */ -- cgit v1.2.3 From 0077c879b57f663c038becdde37b2f6671f59150 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 13:00:35 -0600 Subject: mesa: added _ElementSize field to gl_client_array Will be handy for bounds checking later... --- src/mesa/main/mtypes.h | 1 + src/mesa/main/varray.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bdb1081ca8..716e5c655d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1541,6 +1541,7 @@ struct gl_client_array const GLubyte *Ptr; /**< Points to array data */ GLboolean Enabled; /**< Enabled flag is a boolean */ GLboolean Normalized; /**< GL_ARB_vertex_program */ + GLuint _ElementSize; /**< size of each element in bytes */ struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ GLuint _MaxElement; /**< max element index into array buffer */ diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 106252e460..629be600d4 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -63,6 +63,8 @@ update_array(GLcontext *ctx, struct gl_client_array *array, array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Ptr = (const GLubyte *) ptr; + array->_ElementSize = elementSize; + #if FEATURE_ARB_vertex_buffer_object _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); -- cgit v1.2.3 From 828aa76f360c96adea1725380c397d04690bfd04 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 13:02:38 -0600 Subject: mesa: use array->BufferObj instead of ctx->Array.ArrayBufferObj No difference, but a little more understandable. --- src/mesa/main/varray.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 629be600d4..527555be0e 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -73,8 +73,8 @@ update_array(GLcontext *ctx, struct gl_client_array *array, * Later in glDrawArrays we'll check if start + count > _MaxElement to * be sure we won't go out of bounds. */ - if (ctx->Array.ArrayBufferObj->Name) - array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size + if (array->BufferObj->Name) + array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - (GLsizeiptrARB) array->Ptr + array->StrideB - elementSize) / array->StrideB; else -- cgit v1.2.3 From 1f75c2daeae71985ec3b9fd8f1431aa33ae35d1e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:09:18 -0600 Subject: mesa: add storage_count field to GLvector4f. Useful for debugging. --- src/mesa/math/m_vector.c | 1 + src/mesa/math/m_vector.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c index dd631376d0..0636421727 100644 --- a/src/mesa/math/m_vector.c +++ b/src/mesa/math/m_vector.c @@ -102,6 +102,7 @@ _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, v->stride = 4 * sizeof(GLfloat); v->size = 2; v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment ); + v->storage_count = count; v->start = (GLfloat *) v->storage; v->data = (GLfloat (*)[4]) v->storage; v->count = 0; diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h index 9112a2b5d5..fcf618a740 100644 --- a/src/mesa/math/m_vector.h +++ b/src/mesa/math/m_vector.h @@ -67,6 +67,7 @@ typedef struct { GLuint size; /**< 2-4 for vertices and 1-4 for texcoords */ GLuint flags; /**< which columns are dirty */ void *storage; /**< self-allocated storage */ + GLuint storage_count; /**< storage size in elements */ } GLvector4f; -- cgit v1.2.3 From 800b14cd378ed708a29230d92031ac7b6ad6a286 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:12:01 -0600 Subject: mesa: GLvector4f:: flags is a GLbitfield, update comments too. --- src/mesa/math/m_vector.c | 4 ++-- src/mesa/math/m_vector.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/math/m_vector.c b/src/mesa/math/m_vector.c index 0636421727..4cbab11a35 100644 --- a/src/mesa/math/m_vector.c +++ b/src/mesa/math/m_vector.c @@ -77,7 +77,7 @@ static const GLubyte size_bits[5] = { * \param storage pointer to storage for the vector's data */ void -_mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) +_mesa_vector4f_init( GLvector4f *v, GLbitfield flags, GLfloat (*storage)[4] ) { v->stride = 4 * sizeof(GLfloat); v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ @@ -96,7 +96,7 @@ _mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) * \param alignment desired memory alignment for the data (in bytes) */ void -_mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, +_mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, GLuint count, GLuint alignment ) { v->stride = 4 * sizeof(GLfloat); diff --git a/src/mesa/math/m_vector.h b/src/mesa/math/m_vector.h index fcf618a740..71281d5758 100644 --- a/src/mesa/math/m_vector.h +++ b/src/mesa/math/m_vector.h @@ -65,15 +65,15 @@ typedef struct { GLuint count; /**< size of the vector (in elements) */ GLuint stride; /**< stride from one element to the next (in bytes) */ GLuint size; /**< 2-4 for vertices and 1-4 for texcoords */ - GLuint flags; /**< which columns are dirty */ + GLbitfield flags; /**< bitmask of VEC_x flags */ void *storage; /**< self-allocated storage */ GLuint storage_count; /**< storage size in elements */ } GLvector4f; -extern void _mesa_vector4f_init( GLvector4f *v, GLuint flags, +extern void _mesa_vector4f_init( GLvector4f *v, GLbitfield flags, GLfloat (*storage)[4] ); -extern void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, +extern void _mesa_vector4f_alloc( GLvector4f *v, GLbitfield flags, GLuint count, GLuint alignment ); extern void _mesa_vector4f_free( GLvector4f *v ); extern void _mesa_vector4f_print( const GLvector4f *v, const GLubyte *, GLboolean ); -- cgit v1.2.3 From b9d0f947f2bcc47047b162e3d7c8f91b6153e02c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:17:25 -0600 Subject: mesa: Compute gl_client_array->_MaxElement during array validation Used to be done in the glVertex/Normal/Color/etc/Pointer() calls but if the VBO was reallocated the size could change. New _NEW_BUFFER_OBJECT state flag. --- src/mesa/main/bufferobj.c | 2 ++ src/mesa/main/mtypes.h | 1 + src/mesa/main/state.c | 88 ++++++++++++++++++++++++++++++++--------------- src/mesa/main/varray.c | 13 ------- 4 files changed, 64 insertions(+), 40 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index c8d160baa9..49f690ddd2 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -958,6 +958,8 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, bufObj->Pointer = NULL; } + FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT); + ASSERT(ctx->Driver.BufferData); /* Give the buffer object to the driver! may be null! */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 716e5c655d..368acde7a1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2619,6 +2619,7 @@ struct gl_matrix_stack #define _NEW_PROGRAM 0x8000000 /**< __GLcontextRec::VertexProgram */ #define _NEW_CURRENT_ATTRIB 0x10000000 /**< __GLcontextRec::Current */ #define _NEW_PROGRAM_CONSTANTS 0x20000000 +#define _NEW_BUFFER_OBJECT 0x40000000 #define _NEW_ALL ~0 /*@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 47e1aaa728..a6411f7b62 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -64,97 +64,131 @@ update_separate_specular(GLcontext *ctx) /** - * Update state dependent on vertex arrays. + * Compute the index of the last array element that can be safely accessed + * in a vertex array. We can really only do this when the array lives in + * a VBO. + * The array->_MaxElement field will be updated. + * Later in glDrawArrays/Elements/etc we can do some bounds checking. + */ +static void +compute_max_element(struct gl_client_array *array) +{ + assert(array->Enabled); + if (array->BufferObj->Name) { + /* Compute the max element we can access in the VBO without going + * out of bounds. + */ + array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size + - (GLsizeiptrARB) array->Ptr + array->StrideB + - array->_ElementSize) / array->StrideB; + } + else { + /* user-space array, no idea how big it is */ + array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ + } +} + + +/** + * Helper for update_arrays(). + * \return min(current min, array->_MaxElement). + */ +static GLuint +update_min(GLuint min, struct gl_client_array *array) +{ + compute_max_element(array); + return MIN2(min, array->_MaxElement); +} + + +/** + * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). + * Need to do this upon new array state or new buffer object state. */ static void update_arrays( GLcontext *ctx ) { - const struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - GLuint i, min; + struct gl_array_object *arrayObj = ctx->Array.ArrayObj; + GLuint i, min = ~0; /* find min of _MaxElement values for all enabled arrays */ /* 0 */ if (ctx->VertexProgram._Current && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = arrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); } else if (arrayObj->Vertex.Enabled) { - min = arrayObj->Vertex._MaxElement; - } - else { - /* can't draw anything without vertex positions! */ - min = 0; + min = update_min(min, &arrayObj->Vertex); } /* 1 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]); } /* no conventional vertex weight array */ /* 2 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); } else if (arrayObj->Normal.Enabled) { - min = MIN2(min, arrayObj->Normal._MaxElement); + min = update_min(min, &arrayObj->Normal); } /* 3 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); } else if (arrayObj->Color.Enabled) { - min = MIN2(min, arrayObj->Color._MaxElement); + min = update_min(min, &arrayObj->Color); } /* 4 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); } else if (arrayObj->SecondaryColor.Enabled) { - min = MIN2(min, arrayObj->SecondaryColor._MaxElement); + min = update_min(min, &arrayObj->SecondaryColor); } /* 5 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); } else if (arrayObj->FogCoord.Enabled) { - min = MIN2(min, arrayObj->FogCoord._MaxElement); + min = update_min(min, &arrayObj->FogCoord); } /* 6 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); } else if (arrayObj->Index.Enabled) { - min = MIN2(min, arrayObj->Index._MaxElement); + min = update_min(min, &arrayObj->Index); } - /* 7 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); } /* 8..15 */ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[i]); } else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { - min = MIN2(min, arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); + min = update_min(min, &arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]); } } @@ -162,13 +196,13 @@ update_arrays( GLcontext *ctx ) if (ctx->VertexProgram._Current) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { if (arrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[i]); } } } if (arrayObj->EdgeFlag.Enabled) { - min = MIN2(min, arrayObj->EdgeFlag._MaxElement); + min = update_min(min, &arrayObj->EdgeFlag); } /* _MaxElement is one past the last legal array element */ @@ -548,7 +582,7 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _DD_NEW_SEPARATE_SPECULAR) update_separate_specular( ctx ); - if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) + if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) update_arrays( ctx ); if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 527555be0e..4d153b1c0b 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -65,22 +65,9 @@ update_array(GLcontext *ctx, struct gl_client_array *array, array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; -#if FEATURE_ARB_vertex_buffer_object _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); - /* Compute the index of the last array element that's inside the buffer. - * Later in glDrawArrays we'll check if start + count > _MaxElement to - * be sure we won't go out of bounds. - */ - if (array->BufferObj->Name) - array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - - (GLsizeiptrARB) array->Ptr + array->StrideB - - elementSize) / array->StrideB; - else -#endif - array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ - ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= dirtyBit; } -- cgit v1.2.3 From dcca97a3e3c1d8f5d27e1177257964eddb9effd3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:23:09 -0600 Subject: mesa: added gl_buffer_object::Written flag (for debug purposes) The flag is set when we data has been written into the buffer object. --- src/mesa/main/bufferobj.c | 6 ++++++ src/mesa/main/mtypes.h | 1 + 2 files changed, 7 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 49f690ddd2..43a8d2ba66 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -962,6 +962,8 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, ASSERT(ctx->Driver.BufferData); + bufObj->Written = GL_TRUE; + /* Give the buffer object to the driver! may be null! */ ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj ); } @@ -982,6 +984,8 @@ _mesa_BufferSubDataARB(GLenum target, GLintptrARB offset, return; } + bufObj->Written = GL_TRUE; + ASSERT(ctx->Driver.BufferSubData); ctx->Driver.BufferSubData( ctx, target, offset, size, data, bufObj ); } @@ -1046,6 +1050,8 @@ _mesa_MapBufferARB(GLenum target, GLenum access) } bufObj->Access = access; + if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) + bufObj->Written = GL_TRUE; return bufObj->Pointer; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 368acde7a1..276bc42eba 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1506,6 +1506,7 @@ struct gl_buffer_object GLsizeiptrARB Size; /**< Size of storage in bytes */ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ GLboolean OnCard; /**< Is buffer in VRAM? (hardware drivers) */ + GLboolean Written; /**< Ever written to? (for debugging) */ }; -- cgit v1.2.3 From 6359ecebec860963886801656ab4e01c4e9ff988 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:39:51 -0600 Subject: mesa: remove unused gl_buffer_object::OnCard field --- src/mesa/main/bufferobj.c | 2 -- src/mesa/main/mtypes.h | 1 - 2 files changed, 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 43a8d2ba66..641e5d7c3b 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -389,7 +389,6 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access, (void) ctx; (void) target; (void) access; - ASSERT(!bufObj->OnCard); /* Just return a direct pointer to the data */ if (bufObj->Pointer) { /* already mapped! */ @@ -413,7 +412,6 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target, { (void) ctx; (void) target; - ASSERT(!bufObj->OnCard); /* XXX we might assert here that bufObj->Pointer is non-null */ bufObj->Pointer = NULL; return GL_TRUE; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 276bc42eba..affb000b8c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1505,7 +1505,6 @@ struct gl_buffer_object GLsizeiptr Length; /**< mapped length */ GLsizeiptrARB Size; /**< Size of storage in bytes */ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ - GLboolean OnCard; /**< Is buffer in VRAM? (hardware drivers) */ GLboolean Written; /**< Ever written to? (for debugging) */ }; -- cgit v1.2.3 From f37cccde3c2f4d63ba45be5b50b2358eb8ef98b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 11:01:02 -0600 Subject: vbo: in glDraw[Range]Element() code, check for out of bounds indexes No-op the bad drawing command rather than go out of bounds and render garbage. Print a warning to alert the developer to the bad drawing call. --- src/mesa/vbo/vbo_exec_array.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 0d4cbe9a1e..f4ad394f51 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -352,6 +352,13 @@ vbo_exec_DrawRangeElements(GLenum mode, if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) return; + if (end >= ctx->Array._MaxElement) { + /* the max element is out of bounds of one or more enabled arrays */ + _mesa_warning(ctx, "glDraw[Range]Elements() index=%u is " + "out of bounds (max=%u)", end, ctx->Array._MaxElement); + return; + } + FLUSH_CURRENT( ctx, 0 ); if (ctx->NewState) -- cgit v1.2.3 From 105c8529e78db961fee832b6248c3bcf59668bad Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:10:48 -0600 Subject: mesa: fix comments, s/texture/buffer/ --- src/mesa/main/bufferobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 641e5d7c3b..a983376251 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -194,7 +194,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, return; if (*ptr) { - /* Unreference the old texture */ + /* Unreference the old buffer */ GLboolean deleteFlag = GL_FALSE; struct gl_buffer_object *oldObj = *ptr; @@ -227,7 +227,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, ASSERT(!*ptr); if (bufObj) { - /* reference new texture */ + /* reference new buffer */ /*_glthread_LOCK_MUTEX(tex->Mutex);*/ if (bufObj->RefCount == 0) { /* this buffer's being deleted (look just above) */ -- cgit v1.2.3 From 4f6b704f9796775d8d9937c3cf75a2901b99b896 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:30:39 -0600 Subject: mesa: move the NullBufferObj from GLcontext to gl_shared_state Since shared array objects may point to the null/default buffer object, the null/default buffer object should be part of the shared state. --- src/mesa/main/arrayobj.c | 5 +++-- src/mesa/main/bufferobj.c | 16 ++++------------ src/mesa/main/context.c | 3 --- src/mesa/main/mtypes.h | 3 ++- src/mesa/main/pixel.c | 12 ++++++------ src/mesa/main/pixelstore.c | 9 ++++++--- src/mesa/main/shared.c | 12 ++++++++++++ src/mesa/swrast/s_imaging.c | 10 +++++----- src/mesa/vbo/vbo_context.c | 9 ++++++--- src/mesa/vbo/vbo_exec_api.c | 4 ++-- src/mesa/vbo/vbo_rebase.c | 2 +- src/mesa/vbo/vbo_split_copy.c | 4 ++-- src/mesa/vbo/vbo_split_inplace.c | 2 +- 13 files changed, 50 insertions(+), 41 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b04095fd16..2646c12ccc 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -112,7 +112,8 @@ init_array(GLcontext *ctx, array->Normalized = GL_FALSE; #if FEATURE_ARB_vertex_buffer_object /* Vertex array buffers */ - array->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &array->BufferObj, + ctx->Shared->NullBufferObj); #endif } @@ -180,7 +181,7 @@ _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) static void unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) { - if (bufObj != ctx->Array.NullBufferObj) { + if (bufObj != ctx->Shared->NullBufferObj) { _mesa_reference_buffer_object(ctx, &bufObj, NULL); } } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index a983376251..1f2070ef47 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -424,16 +424,8 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target, void _mesa_init_buffer_objects( GLcontext *ctx ) { - /* Allocate the default buffer object and set refcount so high that - * it never gets deleted. - * XXX with recent/improved refcounting this may not longer be needed. - */ - ctx->Array.NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0); - if (ctx->Array.NullBufferObj) - ctx->Array.NullBufferObj->RefCount = 1000; - - ctx->Array.ArrayBufferObj = ctx->Array.NullBufferObj; - ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj; + ctx->Array.ArrayBufferObj = ctx->Shared->NullBufferObj; + ctx->Array.ElementArrayBufferObj = ctx->Shared->NullBufferObj; } @@ -477,7 +469,7 @@ bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer) /* The spec says there's not a buffer object named 0, but we use * one internally because it simplifies things. */ - newBufObj = ctx->Array.NullBufferObj; + newBufObj = ctx->Shared->NullBufferObj; } else { /* non-default buffer object */ @@ -744,7 +736,7 @@ unbind(GLcontext *ctx, struct gl_buffer_object *obj) { if (*ptr == obj) { - _mesa_reference_buffer_object(ctx, ptr, ctx->Array.NullBufferObj); + _mesa_reference_buffer_object(ctx, ptr, ctx->Shared->NullBufferObj); } } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index d780f91f04..1a290f251a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1005,9 +1005,6 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free_query_data(ctx); #endif -#if FEATURE_ARB_vertex_buffer_object - _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj); -#endif _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); /* free dispatch tables */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index affb000b8c..3debbe9f2d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1593,7 +1593,6 @@ struct gl_array_attrib GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */ #if FEATURE_ARB_vertex_buffer_object - struct gl_buffer_object *NullBufferObj; struct gl_buffer_object *ArrayBufferObj; struct gl_buffer_object *ElementArrayBufferObj; #endif @@ -2064,6 +2063,8 @@ struct gl_shared_state GLuint TextureStateStamp; /**< state notification for shared tex */ /*@}*/ + /** Default buffer object for vertex arrays that aren't in VBOs */ + struct gl_buffer_object *NullBufferObj; /** * \name Vertex/fragment programs diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 57ae9c721a..d9f3e476e8 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -170,7 +170,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -229,7 +229,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -303,7 +303,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -371,7 +371,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); @@ -432,7 +432,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); @@ -494,7 +494,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); diff --git a/src/mesa/main/pixelstore.c b/src/mesa/main/pixelstore.c index ff1a6344cc..6a641f83f2 100644 --- a/src/mesa/main/pixelstore.c +++ b/src/mesa/main/pixelstore.c @@ -245,7 +245,8 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->Pack.ClientStorage = GL_FALSE; ctx->Pack.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->Pack.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, + ctx->Shared->NullBufferObj); #endif ctx->Unpack.Alignment = 4; ctx->Unpack.RowLength = 0; @@ -258,7 +259,8 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->Unpack.ClientStorage = GL_FALSE; ctx->Unpack.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, + ctx->Shared->NullBufferObj); #endif /* @@ -278,6 +280,7 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->DefaultPacking.ClientStorage = GL_FALSE; ctx->DefaultPacking.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, + ctx->Shared->NullBufferObj); #endif } diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index ae8dd2a836..759883743d 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -33,6 +33,7 @@ #include "mtypes.h" #include "hash.h" #include "arrayobj.h" +#include "bufferobj.h" #include "shared.h" #include "shader/program.h" #include "shader/shader_api.h" @@ -92,6 +93,13 @@ _mesa_alloc_shared_state(GLcontext *ctx) shared->BufferObjects = _mesa_NewHashTable(); #endif + /* Allocate the default buffer object and set refcount so high that + * it never gets deleted. + * XXX with recent/improved refcounting this may not longer be needed. + */ + shared->NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0); + shared->NullBufferObj->RefCount = 1000; + shared->ArrayObjects = _mesa_NewHashTable(); /* Create default texture objects */ @@ -341,6 +349,10 @@ _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) _mesa_DeleteHashTable(shared->RenderBuffers); #endif +#if FEATURE_ARB_vertex_buffer_object + _mesa_delete_buffer_object(ctx, shared->NullBufferObj); +#endif + /* * Free texture objects (after FBOs since some textures might have * been bound to FBOs). diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c index d6be3aa022..3578b713f6 100644 --- a/src/mesa/swrast/s_imaging.c +++ b/src/mesa/swrast/s_imaging.c @@ -60,7 +60,7 @@ _swrast_CopyColorTable( GLcontext *ctx, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data); @@ -94,7 +94,7 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data); @@ -126,7 +126,7 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; /* store as convolution filter */ _mesa_ConvolutionFilter1D(target, internalFormat, width, @@ -178,12 +178,12 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, ctx->Unpack.SkipImages = 0; ctx->Unpack.SwapBytes = GL_FALSE; ctx->Unpack.LsbFirst = GL_FALSE; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; ctx->NewState |= _NEW_PACKUNPACK; /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ConvolutionFilter2D(target, internalFormat, width, height, GL_RGBA, CHAN_TYPE, rgba); diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index ca8190fd05..f193a4bf1e 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -28,6 +28,7 @@ #include "main/imports.h" #include "main/mtypes.h" #include "main/api_arrayelt.h" +#include "main/bufferobj.h" #include "math/m_eval.h" #include "vbo.h" #include "vbo_context.h" @@ -81,7 +82,8 @@ static void init_legacy_currval(GLcontext *ctx) cl->Type = GL_FLOAT; cl->Format = GL_RGBA; cl->Ptr = (const void *)ctx->Current.Attrib[i]; - cl->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &cl->BufferObj, + ctx->Shared->NullBufferObj); } } @@ -106,7 +108,8 @@ static void init_generic_currval(GLcontext *ctx) cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &cl->BufferObj, + ctx->Shared->NullBufferObj); } } @@ -150,7 +153,7 @@ static void init_mat_currval(GLcontext *ctx) cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; + cl->BufferObj = ctx->Shared->NullBufferObj; } } diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 5d35ec9c11..6871ee5cab 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -671,7 +671,7 @@ void vbo_use_buffer_objects(GLcontext *ctx) GLsizei size = VBO_VERT_BUFFER_SIZE; /* Make sure this func is only used once */ - assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj); + assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj); if (exec->vtx.buffer_map) { _mesa_align_free(exec->vtx.buffer_map); exec->vtx.buffer_map = NULL; @@ -697,7 +697,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, - ctx->Array.NullBufferObj); + ctx->Shared->NullBufferObj); ASSERT(!exec->vtx.buffer_map); exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64); diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index dae778e741..ea87dede64 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -161,7 +161,7 @@ void vbo_rebase_prims( GLcontext *ctx, GL_ELEMENT_ARRAY_BUFFER, ib->obj); - tmp_ib.obj = ctx->Array.NullBufferObj; + tmp_ib.obj = ctx->Shared->NullBufferObj; tmp_ib.ptr = tmp_indices; tmp_ib.count = ib->count; tmp_ib.type = ib->type; diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 56a9fafac4..2f6a1998ea 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -459,7 +459,7 @@ replay_init( struct copy_context *copy ) dst->Ptr = copy->dstbuf + offset; dst->Enabled = GL_TRUE; dst->Normalized = src->Normalized; - dst->BufferObj = ctx->Array.NullBufferObj; + dst->BufferObj = ctx->Shared->NullBufferObj; dst->_MaxElement = copy->dstbuf_size; /* may be less! */ offset += copy->varying[i].size; @@ -479,7 +479,7 @@ replay_init( struct copy_context *copy ) */ copy->dstib.count = 0; /* duplicates dstelt_nr */ copy->dstib.type = GL_UNSIGNED_INT; - copy->dstib.obj = ctx->Array.NullBufferObj; + copy->dstib.obj = ctx->Shared->NullBufferObj; copy->dstib.ptr = copy->dstelt; } diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index fbc856e93b..3ed6b34fbf 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -221,7 +221,7 @@ static void split_prims( struct split_context *split) ib.count = count; ib.type = GL_UNSIGNED_INT; - ib.obj = split->ctx->Array.NullBufferObj; + ib.obj = split->ctx->Shared->NullBufferObj; ib.ptr = elts; tmpprim = *prim; -- cgit v1.2.3 From 9bb6684799f00fabc313ee50be671454e498d8a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:36:20 -0600 Subject: mesa: array object comments --- src/mesa/main/mtypes.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3debbe9f2d..b24366d0fe 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,6 +1557,8 @@ struct gl_array_object /** Name of the array object as received from glGenVertexArrayAPPLE. */ GLuint Name; + /** XXX Need a refcount here */ + /** Conventional vertex arrays */ /*@{*/ struct gl_client_array Vertex; @@ -1583,7 +1585,10 @@ struct gl_array_object */ struct gl_array_attrib { + /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */ struct gl_array_object *ArrayObj; + + /** The default vertex array object */ struct gl_array_object *DefaultArrayObj; GLint ActiveTexture; /**< Client Active Texture */ -- cgit v1.2.3 From 1030bf0ded2a88a5e27f7a4d393c11cfde3d3c5a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:52:26 -0600 Subject: mesa: reference counting for gl_array_object Every kind of object that can be shared by multiple contexts should be refcounted. --- src/mesa/main/arrayobj.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--- src/mesa/main/arrayobj.h | 23 ++++++++++++----- src/mesa/main/mtypes.h | 3 ++- src/mesa/main/varray.c | 4 +-- 4 files changed, 83 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 2646c12ccc..71f4216bd3 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -94,10 +94,69 @@ void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) { (void) ctx; + _glthread_DESTROY_MUTEX(obj->Mutex); _mesa_free(obj); } +/** + * Set ptr to arrayObj w/ reference counting. + */ +void +_mesa_reference_array_object(GLcontext *ctx, + struct gl_array_object **ptr, + struct gl_array_object *arrayObj) +{ + if (*ptr == arrayObj) + return; + + if (*ptr) { + /* Unreference the old array object */ + GLboolean deleteFlag = GL_FALSE; + struct gl_array_object *oldObj = *ptr; + + _glthread_LOCK_MUTEX(oldObj->Mutex); + ASSERT(oldObj->RefCount > 0); + oldObj->RefCount--; +#if 0 + printf("ArrayObj %p %d DECR to %d\n", + (void *) oldObj, oldObj->Name, oldObj->RefCount); +#endif + deleteFlag = (oldObj->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldObj->Mutex); + + if (deleteFlag) { + ASSERT(ctx->Driver.DeleteArrayObject); + ctx->Driver.DeleteArrayObject(ctx, oldObj); + } + + *ptr = NULL; + } + ASSERT(!*ptr); + + if (arrayObj) { + /* reference new array object */ + _glthread_LOCK_MUTEX(arrayObj->Mutex); + if (arrayObj->RefCount == 0) { + /* this array's being deleted (look just above) */ + /* Not sure this can every really happen. Warn if it does. */ + _mesa_problem(NULL, "referencing deleted array object"); + *ptr = NULL; + } + else { + arrayObj->RefCount++; +#if 0 + printf("ArrayObj %p %d INCR to %d\n", + (void *) arrayObj, arrayObj->Name, arrayObj->RefCount); +#endif + *ptr = arrayObj; + } + _glthread_UNLOCK_MUTEX(arrayObj->Mutex); + } +} + + + static void init_array(GLcontext *ctx, struct gl_client_array *array, GLint size, GLint type) @@ -130,6 +189,9 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->Name = name; + _glthread_INIT_MUTEX(obj->Mutex); + obj->RefCount = 1; + /* Init the individual arrays */ init_array(ctx, &obj->Vertex, 4, GL_FLOAT); init_array(ctx, &obj->Normal, 3, GL_FLOAT); @@ -227,7 +289,6 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) if (!newObj) { /* If this is a new array object id, allocate an array object now. */ - newObj = (*ctx->Driver.NewArrayObject)(ctx, id); if (!newObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); @@ -237,11 +298,9 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) } } - ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= _NEW_ARRAY_ALL; - ctx->Array.ArrayObj = newObj; - + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj); /* Pass BindVertexArray call to device driver */ if (ctx->Driver.BindArrayObject && newObj) diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index c7d66ec166..9c4036af5a 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -41,17 +41,26 @@ * Internal functions */ -struct gl_array_object * _mesa_new_array_object( GLcontext *ctx, - GLuint name ); +extern struct gl_array_object * +_mesa_new_array_object( GLcontext *ctx, GLuint name ); -void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ); -void _mesa_initialize_array_object( GLcontext *ctx, - struct gl_array_object *obj, GLuint name ); +extern void +_mesa_reference_array_object(GLcontext *ctx, + struct gl_array_object **ptr, + struct gl_array_object *arrayObj); -void _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_initialize_array_object( GLcontext *ctx, + struct gl_array_object *obj, GLuint name ); -void _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); + +extern void +_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b24366d0fe..d11df535f2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,7 +1557,8 @@ struct gl_array_object /** Name of the array object as received from glGenVertexArrayAPPLE. */ GLuint Name; - /** XXX Need a refcount here */ + GLint RefCount; + _glthread_Mutex Mutex; /** Conventional vertex arrays */ /*@{*/ diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 4d153b1c0b..a9c9162be1 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1039,7 +1039,7 @@ void _mesa_init_varray(GLcontext *ctx) { ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); - ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj; - + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, + ctx->Array.DefaultArrayObj); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ } -- cgit v1.2.3 From 32b851c80792623195069d7a41a5808cff3b2f6f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 14:26:17 -0600 Subject: mesa: clean-up vertex array object VBO unbinding and delete/refcounting Don't really delete vertex array objects until the refcount hits zero. At that time, unbind any pointers to VBOs. --- src/mesa/main/arrayobj.c | 64 +++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 71f4216bd3..b4d1a77b97 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -68,6 +68,32 @@ lookup_arrayobj(GLcontext *ctx, GLuint id) } +/** + * For all the vertex arrays in the array object, unbind any pointers + * to any buffer objects (VBOs). + * This is done just prior to array object destruction. + */ +static void +unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) +{ + GLuint i; + + _mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->FogCoord.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL); + + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) + _mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL); + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL); +} + + /** * Allocate and initialize a new vertex array object. * @@ -94,6 +120,7 @@ void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) { (void) ctx; + unbind_array_object_vbos(ctx, obj); _glthread_DESTROY_MUTEX(obj->Mutex); _mesa_free(obj); } @@ -240,15 +267,6 @@ _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) } -static void -unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) -{ - if (bufObj != ctx->Shared->NullBufferObj) { - _mesa_reference_buffer_object(ctx, &bufObj, NULL); - } -} - - /**********************************************************************/ /* API Functions */ /**********************************************************************/ @@ -275,7 +293,7 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) return; /* rebinding the same array object- no change */ /* - * Get pointer to new array object (newBufObj) + * Get pointer to new array object (newObj) */ if (id == 0) { /* The spec says there is no array object named 0, but we use @@ -334,7 +352,6 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) if ( obj != NULL ) { ASSERT( obj->Name == ids[i] ); - /* If the array object is currently bound, the spec says "the binding * for that object reverts to zero and the default vertex array * becomes current." @@ -343,28 +360,13 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) CALL_BindVertexArrayAPPLE( ctx->Exec, (0) ); } -#if FEATURE_ARB_vertex_buffer_object - /* Unbind any buffer objects that might be bound to arrays in - * this array object. - */ - unbind_buffer_object( ctx, obj->Vertex.BufferObj ); - unbind_buffer_object( ctx, obj->Normal.BufferObj ); - unbind_buffer_object( ctx, obj->Color.BufferObj ); - unbind_buffer_object( ctx, obj->SecondaryColor.BufferObj ); - unbind_buffer_object( ctx, obj->FogCoord.BufferObj ); - unbind_buffer_object( ctx, obj->Index.BufferObj ); - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - unbind_buffer_object( ctx, obj->TexCoord[i].BufferObj ); - } - unbind_buffer_object( ctx, obj->EdgeFlag.BufferObj ); - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - unbind_buffer_object( ctx, obj->VertexAttrib[i].BufferObj ); - } -#endif - /* The ID is immediately freed for re-use */ _mesa_remove_array_object(ctx, obj); - ctx->Driver.DeleteArrayObject(ctx, obj); + + /* Unreference the array object. + * If refcount hits zero, the object will be deleted. + */ + _mesa_reference_array_object(ctx, &obj, NULL); } } -- cgit v1.2.3 From fa95ecb467d656e293a12c089b3e85fcbbadb848 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 14:33:18 -0600 Subject: mesa: make the array object save/remove functions static --- src/mesa/main/arrayobj.c | 14 +++++++------- src/mesa/main/arrayobj.h | 7 ------- 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b4d1a77b97..8ec73b9526 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -243,8 +243,8 @@ _mesa_initialize_array_object( GLcontext *ctx, /** * Add the given array object to the array object pool. */ -void -_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ) +static void +save_array_object( GLcontext *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* insert into hash table */ @@ -257,8 +257,8 @@ _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ) * Remove the given array object from the array object pool. * Do not deallocate the array object though. */ -void -_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) +static void +remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* remove from hash table */ @@ -312,7 +312,7 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); return; } - _mesa_save_array_object(ctx, newObj); + save_array_object(ctx, newObj); } } @@ -361,7 +361,7 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) } /* The ID is immediately freed for re-use */ - _mesa_remove_array_object(ctx, obj); + remove_array_object(ctx, obj); /* Unreference the array object. * If refcount hits zero, the object will be deleted. @@ -415,7 +415,7 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE"); return; } - _mesa_save_array_object(ctx, obj); + save_array_object(ctx, obj); arrays[i] = first + i; } diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 9c4036af5a..9c2f340cfa 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -56,13 +56,6 @@ extern void _mesa_initialize_array_object( GLcontext *ctx, struct gl_array_object *obj, GLuint name ); -extern void -_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); - -extern void -_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); - - /* * API functions -- cgit v1.2.3 From b25168c34c60760a33ca9e8336ac76cf1219f143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 1 May 2009 18:52:54 +0100 Subject: mesa: Make _mesa_share_state thread safe. --- src/mesa/main/context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 1a290f251a..ddbc631e67 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1394,14 +1394,21 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { struct gl_shared_state *oldSharedState = ctx->Shared; + GLint RefCount; ctx->Shared = ctxToShare->Shared; + + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); ctx->Shared->RefCount++; + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); update_default_objects(ctx); - oldSharedState->RefCount--; - if (oldSharedState->RefCount == 0) { + _glthread_LOCK_MUTEX(oldSharedState->Mutex); + RefCount = --oldSharedState->RefCount; + _glthread_UNLOCK_MUTEX(oldSharedState->Mutex); + + if (RefCount == 0) { _mesa_free_shared_state(ctx, oldSharedState); } -- cgit v1.2.3 From 01280cff537544299fe0c5f1a282abde8e69b1f3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 11:46:08 +0100 Subject: mesa/st: cope with non-ibo index data in st_draw_feedback.c Previously only non-indexed or indicies-in-a-vbo cases were handled in this code. This change adds the missing regular indices-in-memory case. --- src/mesa/state_tracker/st_draw_feedback.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index e533afd051..32502a9cda 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -196,13 +196,10 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_vertex_elements(draw, vp->num_inputs, velements); if (ib) { - unsigned indexSize; struct gl_buffer_object *bufobj = ib->obj; - struct st_buffer_object *stobj = st_buffer_object(bufobj); + unsigned indexSize; void *map; - index_buffer_handle = stobj->buffer; - switch (ib->type) { case GL_UNSIGNED_INT: indexSize = 4; @@ -215,9 +212,19 @@ st_feedback_draw_vbo(GLcontext *ctx, return; } - map = pipe_buffer_map(pipe->screen, index_buffer_handle, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, map); + if (bufobj && bufobj->Name) { + struct st_buffer_object *stobj = st_buffer_object(bufobj); + + index_buffer_handle = stobj->buffer; + + map = pipe_buffer_map(pipe->screen, index_buffer_handle, + PIPE_BUFFER_USAGE_CPU_READ); + + draw_set_mapped_element_buffer(draw, indexSize, map); + } + else { + draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr); + } } else { /* no index/element buffer */ @@ -252,7 +259,7 @@ st_feedback_draw_vbo(GLcontext *ctx, draw_set_mapped_vertex_buffer(draw, i, NULL); } } - if (ib) { + if (index_buffer_handle) { pipe_buffer_unmap(pipe->screen, index_buffer_handle); draw_set_mapped_element_buffer(draw, 0, NULL); } -- cgit v1.2.3 From 6826bad6a75e78729dd472ea26c87787c90ada4c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:27:30 +0100 Subject: mesa/st: remove redundant call to st_finish in CopyTexSubImage Rendering should already have been flushed, any synchronization will be done by the driver or memory manager. --- src/mesa/state_tracker/st_cb_texture.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b7b791d9a4..98f109fc65 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1315,9 +1315,6 @@ st_copy_texsubimage(GLcontext *ctx, GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - /* any rendering in progress must complete before we grab the fb image */ - st_finish(ctx->st); - /* make sure finalize_textures has been called? */ if (0) st_validate_state(ctx->st); -- cgit v1.2.3 From d5c2ad8514ce8064d83febf647c9e726788b7924 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 7 May 2009 19:48:06 +0100 Subject: mesa/st: keep surface_copy arguments positive The src/dest x,y, and w,h arguments of the pipe->surface_copy function are unsigned and the drivers aren't expecting negative (or extremly-large unsigned) values as inputs. Trim the requests at the state-tracker level before passing down. --- src/mesa/state_tracker/st_cb_drawpixels.c | 43 ++++++++++++++++++++++++++++--- src/mesa/state_tracker/st_cb_texture.c | 28 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 08dc7c930e..89725cfe8d 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -910,6 +910,34 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, st_validate_state(st); + if (srcx < 0) { + width -= -srcx; + dstx += -srcx; + srcx = 0; + } + + if (srcy < 0) { + height -= -srcy; + dsty += -srcy; + srcy = 0; + } + + if (dstx < 0) { + width -= -dstx; + srcx += -dstx; + dstx = 0; + } + + if (dsty < 0) { + height -= -dsty; + srcy += -dsty; + dsty = 0; + } + + if (width < 0 || height < 0) + return; + + if (type == GL_STENCIL) { /* can't use texturing to do stencil */ copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); @@ -951,15 +979,24 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, } } + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + srcy = ctx->DrawBuffer->Height - srcy - height; + + if (srcy < 0) { + height -= -srcy; + srcy = 0; + } + + if (height < 0) + return; + } + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0, width, height, 1, PIPE_TEXTURE_USAGE_SAMPLER); if (!pt) return; - if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcy = ctx->DrawBuffer->Height - srcy - height; - } if (srcFormat == texFormat) { /* copy source framebuffer surface into mipmap/texture */ diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 98f109fc65..b182106fd5 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1337,6 +1337,34 @@ st_copy_texsubimage(GLcontext *ctx, return; } + if (srcX < 0) { + width -= -srcX; + destX += -srcX; + srcX = 0; + } + + if (srcY < 0) { + height -= -srcY; + destY += -srcY; + srcY = 0; + } + + if (destX < 0) { + width -= -destX; + srcX += -destX; + destX = 0; + } + + if (destY < 0) { + height -= -destY; + srcY += -destY; + destY = 0; + } + + if (width < 0 || height < 0) + return; + + assert(strb); assert(strb->surface); assert(stImage->pt); -- cgit v1.2.3 From ccaa6463a7a327bb5fe122af41ea77e158439cce Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 12:17:11 -0600 Subject: mesa: more shader debug code (disabled) --- src/mesa/shader/shader_api.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 8f414a0889..a8390d3094 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1509,6 +1509,10 @@ _mesa_use_program(GLcontext *ctx, GLuint program) shProg->Shaders[i]->Name, shProg->Shaders[i]->Type); } + if (shProg->VertexProgram) + printf(" vert prog %u\n", shProg->VertexProgram->Base.Id); + if (shProg->FragmentProgram) + printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id); } } else { -- cgit v1.2.3 From 40cba5489d963d4903d9c2385775f880824310da Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 12:18:44 -0600 Subject: glsl: set vertex/fragment program Ids to aid with debugging --- src/mesa/shader/slang/slang_link.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 1fdf4db054..798eb13f20 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -712,6 +712,8 @@ _slang_link(GLcontext *ctx, struct gl_vertex_program *linked_vprog = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); shProg->VertexProgram = linked_vprog; /* refcount OK */ + /* vertex program ID not significant; just set Id for debugging purposes */ + shProg->VertexProgram->Base.Id = shProg->Name; ASSERT(shProg->VertexProgram->Base.RefCount == 1); } @@ -720,6 +722,8 @@ _slang_link(GLcontext *ctx, struct gl_fragment_program *linked_fprog = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); shProg->FragmentProgram = linked_fprog; /* refcount OK */ + /* vertex program ID not significant; just set Id for debugging purposes */ + shProg->FragmentProgram->Base.Id = shProg->Name; ASSERT(shProg->FragmentProgram->Base.RefCount == 1); } -- cgit v1.2.3 From e2cf522de09bc4afa18ef8d98db69973ee489d58 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 12:43:58 -0600 Subject: i965: don't use GRF regs 126,127 for WM programs They seem to be used for something else and using them for shader temps seems to lead to GPU lock-ups. Call _mesa_warning() when we run out of temps. Also, clean up some debug code. --- src/mesa/drivers/dri/i965/brw_wm.h | 2 ++ src/mesa/drivers/dri/i965/brw_wm_glsl.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 2f80a60c12..59ead757b5 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -242,6 +242,8 @@ struct brw_wm_compile { GLuint cur_inst; /**< index of current instruction */ + GLboolean out_of_regs; /**< ran out of GRF registers? */ + /** Mapping from Mesa registers to hardware registers */ struct { GLboolean inited; diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index cc2c6ab189..efe8b5126c 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -96,8 +96,15 @@ alloc_grf(struct brw_wm_compile *c) for (r = 0; r < BRW_WM_MAX_GRF; r++) { assert(c->used_grf[r]); } - /*printf("Really out of temp regs!\n");*/ - return 60; + + /* really, no free GRF regs found */ + if (!c->out_of_regs) { + /* print warning once per compilation */ + _mesa_warning(NULL, "i965: ran out of registers for fragment program"); + c->out_of_regs = GL_TRUE; + } + + return -1; } @@ -143,7 +150,12 @@ static struct brw_reg alloc_tmp(struct brw_wm_compile *c) /* if we need to allocate another temp, grow the tmp_regs[] array */ if (c->tmp_index == c->tmp_max) { - c->tmp_regs[ c->tmp_max++ ] = alloc_grf(c); + int r = alloc_grf(c); + if (r < 0) { + /*printf("Out of temps in %s\n", __FUNCTION__);*/ + r = 50; /* XXX random register! */ + } + c->tmp_regs[ c->tmp_max++ ] = r; } /* form the GRF register */ @@ -210,6 +222,8 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, } assert(index < 256); + assert(component < 4); + /* see if we've already allocated a HW register for this Mesa register */ if (c->wm_regs[file][index][component].inited) { /* yes, re-use */ @@ -218,9 +232,10 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component, else { /* no, allocate new register */ int grf = alloc_grf(c); + /*printf("alloc grf %d for reg %d:%d.%d\n", grf, file, index, component);*/ if (grf < 0) { /* totally out of temps */ - grf = 70; /* XXX !!!! */ + grf = 51; /* XXX random register! */ } reg = brw_vec8_grf(grf, 0); @@ -373,6 +388,10 @@ static void prealloc_reg(struct brw_wm_compile *c) for (i = 0; i < reg_index; i++) prealloc_grf(c, i); + /* Don't use GRF 126, 127. Using them seems to lead to GPU lock-ups */ + prealloc_grf(c, 126); + prealloc_grf(c, 127); + /* An instruction may reference up to three constants. * They'll be found in these registers. * XXX alloc these on demand! @@ -385,7 +404,7 @@ static void prealloc_reg(struct brw_wm_compile *c) } #if 0 printf("USE CONST BUFFER? %d\n", c->fp->use_const_buffer); - printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index); + printf("AFTER PRE_ALLOC, reg_index = %d\n", reg_index); #endif } @@ -2717,6 +2736,8 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) struct brw_compile *p = &c->func; struct brw_indirect stack_index = brw_indirect(0, 0); + c->out_of_regs = GL_FALSE; + prealloc_reg(c); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); -- cgit v1.2.3 From 87fbc9a14ed2bdd24d84c38431abbf7b0c275998 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 12:44:38 -0600 Subject: mesa: issue warning for out of bounds array indexes --- src/mesa/main/api_validate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 27049486ee..d5c604c56a 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -184,6 +184,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ + _mesa_warning(ctx, "glDrawElements() index=%u is " + "out of bounds (max=%u)", max, ctx->Array._MaxElement); return GL_FALSE; } } -- cgit v1.2.3 From cc58fbcf2c5c88f406818db60910f537e03610d6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 14:32:19 -0600 Subject: glsl: check number of varying variables against the limit Link fails if too many varying vars. --- src/mesa/shader/slang/slang_link.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 798eb13f20..2bc8809661 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -97,7 +97,8 @@ bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit) * which inputs are centroid-sampled, invariant, etc. */ static GLboolean -link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) +link_varying_vars(GLcontext *ctx, + struct gl_shader_program *shProg, struct gl_program *prog) { GLuint *map, i, firstVarying, newFile; GLbitfield *inOutFlags; @@ -156,8 +157,12 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) var->Flags); } + if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) { + link_error(shProg, "Too many varying variables"); + return GL_FALSE; + } + /* Map varying[i] to varying[j]. - * Plus, set prog->Input/OutputFlags[] as described above. * Note: the loop here takes care of arrays or large (sz>4) vars. */ { @@ -729,11 +734,11 @@ _slang_link(GLcontext *ctx, /* link varying vars */ if (shProg->VertexProgram) { - if (!link_varying_vars(shProg, &shProg->VertexProgram->Base)) + if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base)) return; } if (shProg->FragmentProgram) { - if (!link_varying_vars(shProg, &shProg->FragmentProgram->Base)) + if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base)) return; } -- cgit v1.2.3 From 17a354a119370df9196a010a31fc71cd8712ec46 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 14:34:15 -0600 Subject: mesa: assertions to check for too many vertex outputs or fragment inputs --- src/mesa/main/context.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index ddbc631e67..5e0f2d7b1b 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -602,6 +602,10 @@ _mesa_init_constants(GLcontext *ctx) ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX); + + /* check that we don't exceed various 32-bit bitfields */ + ASSERT(VERT_RESULT_MAX <= 32); + ASSERT(FRAG_ATTRIB_MAX <= 32); } -- cgit v1.2.3 From 4e762395ef7e8c332c16fd0c11025cfa52763a45 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 14:34:43 -0600 Subject: mesa: raise MAX_VARYING (number of shader varying vars) to 16 16 is the limit for now because of various 32-bit bitfields. --- src/mesa/main/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 2a9fdf9ca0..888e08ff93 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -187,7 +187,7 @@ #define MAX_PROGRAM_TEMPS 256 #define MAX_PROGRAM_ADDRESS_REGS 2 #define MAX_UNIFORMS 1024 /**< number of vec4 uniforms */ -#define MAX_VARYING 8 /**< number of float[4] vectors */ +#define MAX_VARYING 16 /**< number of float[4] vectors */ #define MAX_SAMPLERS MAX_TEXTURE_IMAGE_UNITS #define MAX_PROGRAM_INPUTS 32 #define MAX_PROGRAM_OUTPUTS 32 -- cgit v1.2.3 From f09e5a5b637822b89ba19b2e306b83f8fc3809d0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 13:48:41 -0600 Subject: i965: const qualifiers --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 0a3debb101..d7f75e3685 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -1225,7 +1225,7 @@ void brw_vs_emit(struct brw_vs_compile *c ) for (insn = 0; insn < nr_insns; insn++) { - struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn]; + const struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn]; struct brw_reg args[3], dst; GLuint i; @@ -1238,7 +1238,7 @@ void brw_vs_emit(struct brw_vs_compile *c ) */ if (inst->Opcode != OPCODE_SWZ) for (i = 0; i < 3; i++) { - struct prog_src_register *src = &inst->SrcReg[i]; + const struct prog_src_register *src = &inst->SrcReg[i]; index = src->Index; file = src->File; if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src) -- cgit v1.2.3 From b6e94f71c2bfc63497e2c8265179f19babe87688 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 8 May 2009 12:46:18 -0700 Subject: intel: Put the constant texcoords used in metaops into a vbo. Make this be its own function for setup/teardown of the binding of these texcoords. No performance difference in the engine demo (I just felt dirty not using a VBO for this), and I think it should be more resilient to interference from current GL state. --- src/mesa/drivers/dri/intel/intel_context.h | 8 +++ src/mesa/drivers/dri/intel/intel_pixel.c | 83 +++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_pixel.h | 3 + src/mesa/drivers/dri/intel/intel_pixel_bitmap.c | 15 +---- src/mesa/drivers/dri/intel/intel_pixel_draw.c | 33 ++-------- 5 files changed, 102 insertions(+), 40 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index d798225ddd..f385027596 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -161,12 +161,20 @@ struct intel_context struct { struct gl_fragment_program *bitmap_fp; struct gl_vertex_program *passthrough_vp; + struct gl_buffer_object *texcoord_vbo; struct gl_fragment_program *saved_fp; GLboolean saved_fp_enable; struct gl_vertex_program *saved_vp; GLboolean saved_vp_enable; + GLboolean saved_texcoord_enable; + struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; + GLenum saved_texcoord_type; + GLsizei saved_texcoord_size, saved_texcoord_stride; + const void *saved_texcoord_ptr; + int saved_active_texture; + GLint saved_vp_x, saved_vp_y; GLsizei saved_vp_width, saved_vp_height; GLenum saved_matrix_mode; diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index fc0ac0b79c..cbdda6b1f9 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -27,9 +27,12 @@ #include "main/enums.h" #include "main/state.h" +#include "main/bufferobj.h" #include "main/context.h" #include "main/enable.h" #include "main/matrix.h" +#include "main/texstate.h" +#include "main/varray.h" #include "main/viewport.h" #include "swrast/swrast.h" #include "shader/arbprogram.h" @@ -334,6 +337,85 @@ intel_meta_restore_fragment_program(struct intel_context *intel) _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); } +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, + { 1.0, 0.0 }, + { 1.0, 1.0 }, + { 0.0, 1.0 } }; + +void +intel_meta_set_default_texrect(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + struct gl_client_array *old_texcoord_array; + + intel->meta.saved_active_texture = ctx->Texture.CurrentUnit; + if (intel->meta.saved_array_vbo == NULL) { + _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, + ctx->Array.ArrayBufferObj); + } + + old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; + intel->meta.saved_texcoord_type = old_texcoord_array->Type; + intel->meta.saved_texcoord_size = old_texcoord_array->Size; + intel->meta.saved_texcoord_stride = old_texcoord_array->Stride; + intel->meta.saved_texcoord_enable = old_texcoord_array->Enabled; + intel->meta.saved_texcoord_ptr = old_texcoord_array->Ptr; + _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, + old_texcoord_array->BufferObj); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + + if (intel->meta.texcoord_vbo == NULL) { + GLuint vbo_name; + + _mesa_GenBuffersARB(1, &vbo_name); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), + default_texcoords, GL_STATIC_DRAW_ARB); + _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, + ctx->Array.ArrayBufferObj); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.texcoord_vbo->Name); + } + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +intel_meta_restore_texcoords(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + /* Restore the old TexCoordPointer */ + if (intel->meta.saved_texcoord_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.saved_texcoord_vbo->Name); + _mesa_reference_buffer_object(ctx, &intel->meta.saved_texcoord_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + _mesa_TexCoordPointer(intel->meta.saved_texcoord_size, + intel->meta.saved_texcoord_type, + intel->meta.saved_texcoord_stride, + intel->meta.saved_texcoord_ptr); + if (!intel->meta.saved_texcoord_enable) + _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + + intel->meta.saved_active_texture); + + if (intel->meta.saved_array_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + intel->meta.saved_array_vbo->Name); + _mesa_reference_buffer_object(ctx, &intel->meta.saved_array_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + void intelInitPixelFuncs(struct dd_function_table *functions) { @@ -355,5 +437,6 @@ intel_free_pixel_state(struct intel_context *intel) _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); + _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); } diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index cb41fa182c..6acf0813c8 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -40,6 +40,9 @@ void intel_meta_set_fragment_program(struct intel_context *intel, const char *prog_string); void intel_meta_restore_fragment_program(struct intel_context *intel); void intel_free_pixel_state(struct intel_context *intel); +void intel_meta_set_default_texrect(struct intel_context *intel); +void intel_meta_set_default_texrect(struct intel_context *intel); +void intel_meta_restore_texcoords(struct intel_context *intel); GLboolean intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 1db7f5594e..b20840b9a0 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -360,7 +360,6 @@ intel_texture_bitmap(GLcontext * ctx, "END\n"; GLuint texname; GLfloat vertices[4][4]; - GLfloat texcoords[4][2]; GLint old_active_texture; GLubyte *unpacked_bitmap; GLubyte *a8_bitmap; @@ -485,22 +484,12 @@ intel_texture_bitmap(GLcontext * ctx, vertices[3][2] = dst_z; vertices[3][3] = 1.0; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); intel_meta_restore_fragment_program(intel); intel_meta_restore_vertex_program(intel); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index e8d5ac8569..abcdcd5724 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -70,7 +70,6 @@ intel_texture_drawpixels(GLcontext * ctx, struct intel_context *intel = intel_context(ctx); GLuint texname; GLfloat vertices[4][4]; - GLfloat texcoords[4][2]; GLfloat z; GLint old_active_texture; GLenum internalFormat; @@ -169,22 +168,13 @@ intel_texture_drawpixels(GLcontext * ctx, vertices[3][2] = z; vertices[3][3] = 1.0; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); @@ -208,7 +198,6 @@ intel_stencil_drawpixels(GLcontext * ctx, struct intel_context *intel = intel_context(ctx); GLuint texname, rb_name, fb_name, old_fb_name; GLfloat vertices[4][2]; - GLfloat texcoords[4][2]; struct intel_renderbuffer *irb; struct intel_renderbuffer *depth_irb; struct gl_renderbuffer *rb; @@ -343,7 +332,6 @@ intel_stencil_drawpixels(GLcontext * ctx, _mesa_free(stencil_pixels); intel_meta_set_passthrough_transform(intel); - vertices[0][0] = x; vertices[0][1] = y; vertices[1][0] = x + width * ctx->Pixel.ZoomX; @@ -353,22 +341,13 @@ intel_stencil_drawpixels(GLcontext * ctx, vertices[3][0] = x; vertices[3][1] = y + height * ctx->Pixel.ZoomY; - texcoords[0][0] = 0.0; - texcoords[0][1] = 0.0; - texcoords[1][0] = 1.0; - texcoords[1][1] = 0.0; - texcoords[2][0] = 1.0; - texcoords[2][1] = 1.0; - texcoords[3][0] = 0.0; - texcoords[3][1] = 1.0; - _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); - _mesa_ClientActiveTextureARB(GL_TEXTURE0); - _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &texcoords); _mesa_Enable(GL_VERTEX_ARRAY); - _mesa_Enable(GL_TEXTURE_COORD_ARRAY); + intel_meta_set_default_texrect(intel); + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + intel_meta_restore_texcoords(intel); intel_meta_restore_transform(intel); _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); -- cgit v1.2.3 From 1d663ae2925ffadf419ddbea9eca8d5706ea6510 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 7 May 2009 22:50:19 -0700 Subject: intel: Add a metaops version of glGenerateMipmapEXT/SGIS_generate_mipmaps. In addition to being HW accelerated, it avoids the incorrect (black) rendering of the mipmaps that SW was doing in fbo-generatemipmap. Improves the performance of the mipmap generation and drawing in fbo-generatemipmap by 30%. --- src/mesa/drivers/dri/i915/intel_generatemipmap.c | 1 + src/mesa/drivers/dri/i965/Makefile | 1 + src/mesa/drivers/dri/i965/intel_generatemipmap.c | 1 + src/mesa/drivers/dri/intel/intel_context.h | 2 + src/mesa/drivers/dri/intel/intel_generatemipmap.c | 283 ++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_pixel.c | 1 + src/mesa/drivers/dri/intel/intel_tex.c | 56 +---- src/mesa/drivers/dri/intel/intel_tex_copy.c | 2 +- src/mesa/drivers/dri/intel/intel_tex_image.c | 22 +- src/mesa/drivers/dri/intel/intel_tex_subimage.c | 10 +- 10 files changed, 303 insertions(+), 76 deletions(-) create mode 120000 src/mesa/drivers/dri/i915/intel_generatemipmap.c create mode 120000 src/mesa/drivers/dri/i965/intel_generatemipmap.c create mode 100644 src/mesa/drivers/dri/intel/intel_generatemipmap.c (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i915/intel_generatemipmap.c b/src/mesa/drivers/dri/i915/intel_generatemipmap.c new file mode 120000 index 0000000000..4c6b37ada0 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_generatemipmap.c @@ -0,0 +1 @@ +../intel/intel_generatemipmap.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 4913c25f74..9712c38725 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -14,6 +14,7 @@ DRIVER_SOURCES = \ intel_decode.c \ intel_extensions.c \ intel_fbo.c \ + intel_generatemipmap.c \ intel_mipmap_tree.c \ intel_regions.c \ intel_screen.c \ diff --git a/src/mesa/drivers/dri/i965/intel_generatemipmap.c b/src/mesa/drivers/dri/i965/intel_generatemipmap.c new file mode 120000 index 0000000000..4c6b37ada0 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_generatemipmap.c @@ -0,0 +1 @@ +../intel/intel_generatemipmap.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index f385027596..c16732d7b5 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -168,6 +168,8 @@ struct intel_context struct gl_vertex_program *saved_vp; GLboolean saved_vp_enable; + struct gl_fragment_program *tex2d_fp; + GLboolean saved_texcoord_enable; struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; GLenum saved_texcoord_type; diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c new file mode 100644 index 0000000000..02804b51fa --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#include "main/glheader.h" +#include "main/enums.h" +#include "main/image.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/bufferobj.h" +#include "main/teximage.h" +#include "main/texenv.h" +#include "main/texobj.h" +#include "main/texstate.h" +#include "main/texparam.h" +#include "main/varray.h" +#include "main/attrib.h" +#include "main/enable.h" +#include "main/buffers.h" +#include "main/fbobject.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/depth.h" +#include "main/hash.h" +#include "main/mipmap.h" +#include "main/blend.h" +#include "glapi/dispatch.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_pixel.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" + +static const char *intel_fp_tex2d = + "!!ARBfp1.0\n" + "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n" + "END\n"; + +static GLboolean +intel_generate_mipmap_level(GLcontext *ctx, GLuint tex_name, + int level, int width, int height) +{ + struct intel_context *intel = intel_context(ctx); + GLfloat vertices[4][2]; + GLint status; + + /* Set to source from the previous level */ + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level - 1); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1); + + /* Set to draw into the current level */ + _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, + tex_name, + level); + /* Choose to render to the color attachment. */ + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + + status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + return GL_FALSE; + + intel_meta_set_passthrough_transform(intel); + + /* XXX: Doing it right would involve setting up the transformation to do + * 0-1 mapping or something, and not changing the vertex data. + */ + vertices[0][0] = 0; + vertices[0][1] = 0; + vertices[1][0] = width; + vertices[1][1] = 0; + vertices[2][0] = width; + vertices[2][1] = height; + vertices[3][0] = 0; + vertices[3][1] = height; + + _mesa_VertexPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), &vertices); + _mesa_Enable(GL_VERTEX_ARRAY); + intel_meta_set_default_texrect(intel); + + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + + intel_meta_restore_texcoords(intel); + intel_meta_restore_transform(intel); + + return GL_TRUE; +} + +static GLboolean +intel_generate_mipmap_2d(GLcontext *ctx, + GLenum target, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + GLint old_active_texture; + int level, max_levels, start_level, end_level; + GLuint fb_name; + GLboolean success = GL_FALSE; + struct gl_framebuffer *saved_fbo = NULL; + + _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | + GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT); + _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + old_active_texture = ctx->Texture.CurrentUnit; + _mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer); + + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_DEPTH_TEST); + _mesa_Disable(GL_STENCIL_TEST); + _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + _mesa_DepthMask(GL_FALSE); + + /* Bind the given texture to GL_TEXTURE_2D with linear filtering for our + * minification. + */ + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB); + _mesa_Enable(GL_TEXTURE_2D); + _mesa_BindTexture(GL_TEXTURE_2D, texObj->Name); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + /* Bind the new renderbuffer to the color attachment point. */ + _mesa_GenFramebuffersEXT(1, &fb_name); + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_name); + + intel_meta_set_fragment_program(intel, &intel->meta.tex2d_fp, + intel_fp_tex2d); + intel_meta_set_passthrough_vertex_program(intel); + + max_levels = _mesa_max_texture_levels(ctx, texObj->Target); + start_level = texObj->BaseLevel; + end_level = texObj->MaxLevel; + + /* Loop generating level+1 from level. */ + for (level = start_level; level < end_level && level < max_levels - 1; level++) { + const struct gl_texture_image *srcImage; + int width, height; + + srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (srcImage->Border != 0) + goto fail; + + width = srcImage->Width / 2; + if (width < 1) + width = 1; + height = srcImage->Height / 2; + if (height < 1) + height = 1; + + if (width == srcImage->Width && + height == srcImage->Height) { + /* Neither _mesa_max_texture_levels nor texObj->MaxLevel are the + * maximum texture level for the object, so break out when we've gone + * over the edge. + */ + break; + } + + /* Make sure that there's space allocated for the target level. + * We could skip this if there's already space allocated and save some + * time. + */ + _mesa_TexImage2D(GL_TEXTURE_2D, level + 1, srcImage->InternalFormat, + width, height, 0, + GL_RGBA, GL_UNSIGNED_INT, NULL); + + if (!intel_generate_mipmap_level(ctx, texObj->Name, level + 1, + width, height)) + goto fail; + } + + success = GL_TRUE; + +fail: + intel_meta_restore_fragment_program(intel); + intel_meta_restore_vertex_program(intel); + + _mesa_DeleteFramebuffersEXT(1, &fb_name); + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); + if (saved_fbo) + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, saved_fbo->Name); + _mesa_reference_framebuffer(&saved_fbo, NULL); + _mesa_PopClientAttrib(); + _mesa_PopAttrib(); + + return success; +} + + +/** + * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap + * level). + * + * The texture object's miptree must be mapped. + * + * It would be really nice if this was just called by Mesa whenever mipmaps + * needed to be regenerated, rather than us having to remember to do so in + * each texture image modification path. + * + * This function should also include an accelerated path. + */ +void +intel_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int face, i; + + /* HW path */ + if (target == GL_TEXTURE_2D && + ctx->Extensions.EXT_framebuffer_object && + ctx->Extensions.ARB_fragment_program && + ctx->Extensions.ARB_vertex_program) { + GLboolean success; + + /* We'll be accessing this texture using GL entrypoints, which should + * be resilient against other access to this texture. + */ + _mesa_unlock_texture(ctx, texObj); + success = intel_generate_mipmap_2d(ctx, target, texObj); + _mesa_lock_texture(ctx, texObj); + + if (success) + return; + } + + /* SW path */ + intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); + _mesa_generate_mipmap(ctx, target, texObj); + intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); + + /* Update the level information in our private data in the new images, since + * it didn't get set as part of a normal TexImage path. + */ + for (face = 0; face < nr_faces; face++) { + for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { + struct intel_texture_image *intelImage; + + intelImage = intel_texture_image(texObj->Image[face][i]); + if (intelImage == NULL) + break; + + intelImage->level = i; + intelImage->face = face; + /* Unreference the miptree to signal that the new Data is a bare + * pointer from mesa. + */ + intel_miptree_release(intel, &intelImage->mt); + } + } +} diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index cbdda6b1f9..36a684b3b8 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -437,6 +437,7 @@ intel_free_pixel_state(struct intel_context *intel) _mesa_reference_vertprog(ctx, &intel->meta.passthrough_vp, NULL); _mesa_reference_fragprog(ctx, &intel->meta.bitmap_fp, NULL); + _mesa_reference_fragprog(ctx, &intel->meta.tex2d_fp, NULL); _mesa_reference_buffer_object(ctx, &intel->meta.texcoord_vbo, NULL); } diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index ae0994b183..fbd6e1d0c3 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -158,60 +158,6 @@ timed_memcpy(void *dest, const void *src, size_t n) } #endif /* DO_DEBUG */ -/** - * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap - * level). - * - * The texture object's miptree must be mapped. - * - * It would be really nice if this was just called by Mesa whenever mipmaps - * needed to be regenerated, rather than us having to remember to do so in - * each texture image modification path. - * - * This function should also include an accelerated path. - */ -void -intel_generate_mipmap(GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - int face, i; - - _mesa_generate_mipmap(ctx, target, texObj); - - /* Update the level information in our private data in the new images, since - * it didn't get set as part of a normal TexImage path. - */ - for (face = 0; face < nr_faces; face++) { - for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { - struct intel_texture_image *intelImage; - - intelImage = intel_texture_image(texObj->Image[face][i]); - if (intelImage == NULL) - break; - - intelImage->level = i; - intelImage->face = face; - /* Unreference the miptree to signal that the new Data is a bare - * pointer from mesa. - */ - intel_miptree_release(intel, &intelImage->mt); - } - } -} - -static void intelGenerateMipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - - intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); - intel_generate_mipmap(ctx, target, texObj); - intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); -} - void intelInitTextureFuncs(struct dd_function_table *functions) { @@ -227,7 +173,7 @@ intelInitTextureFuncs(struct dd_function_table *functions) functions->CopyTexSubImage1D = intelCopyTexSubImage1D; functions->CopyTexSubImage2D = intelCopyTexSubImage2D; functions->GetTexImage = intelGetTexImage; - functions->GenerateMipmap = intelGenerateMipmap; + functions->GenerateMipmap = intel_generate_mipmap; /* compressed texture functions */ functions->CompressedTexImage2D = intelCompressedTexImage2D; diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 08437aa0e2..7c2b26ef1d 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -158,7 +158,7 @@ do_copy_texsubimage(struct intel_context *intel, /* GL_SGIS_generate_mipmap */ if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) { - ctx->Driver.GenerateMipmap(ctx, target, texObj); + intel_generate_mipmap(ctx, target, texObj); } return GL_TRUE; diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 1f192dafbe..b71fe2a7ae 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -316,7 +316,6 @@ intelTexImage(GLcontext * ctx, GLint postConvHeight = height; GLint texelBytes, sizeInBytes; GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; - GLboolean needs_map; DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); @@ -482,15 +481,8 @@ intelTexImage(GLcontext * ctx, LOCK_HARDWARE(intel); - /* Two cases where we need a mapping of the miptree: when the user supplied - * data is mapped as well (non-PBO, memcpy upload) or when we're going to do - * (software) mipmap generation. - */ - needs_map = (pixels != NULL) || (level == texObj->BaseLevel && - texObj->GenerateMipmap); - if (intelImage->mt) { - if (needs_map) + if (pixels != NULL) texImage->Data = intel_miptree_image_map(intel, intelImage->mt, intelImage->face, @@ -547,22 +539,22 @@ intelTexImage(GLcontext * ctx, format, type, pixels, unpack)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } - - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } } _mesa_unmap_teximage_pbo(ctx, unpack); if (intelImage->mt) { - if (needs_map) + if (pixels != NULL) intel_miptree_image_unmap(intel, intelImage->mt); texImage->Data = NULL; } UNLOCK_HARDWARE(intel); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, texObj); + } } void diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c index f86de56897..48104de2a9 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c @@ -101,11 +101,6 @@ intelTexSubimage(GLcontext * ctx, _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); } - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, texObj); - } - _mesa_unmap_teximage_pbo(ctx, packing); if (intelImage->mt) { @@ -114,6 +109,11 @@ intelTexSubimage(GLcontext * ctx, } UNLOCK_HARDWARE(intel); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, texObj); + } } -- cgit v1.2.3 From c230767d6956b63a2b101acb48f98823bb5dd31a Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 8 May 2009 11:13:57 -0600 Subject: mesa: Fixed a texture memory leak The current texture for any particular texture unit is given an additional reference in update_texture_state(); but if the context is closed before that texture can be released (which is quite frequent in normal use, unless a program unbinds and deletes the texture and renders without it to force a call to update_texture_state(), the memory is lost. This affects general Mesa; but the i965 is particularly affected because it allocates a considerable amount of additional memory for each allocated texture. --- src/mesa/main/texstate.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 5453331c67..6e0c0c688a 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -791,6 +791,9 @@ _mesa_free_texture_data(GLcontext *ctx) /* unreference current textures */ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + /* The _Current texture could account for another reference */ + _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL); } -- cgit v1.2.3 From 44a4abfd4f8695809eaec07df8eeb191d6e017d7 Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 8 May 2009 14:40:38 -0600 Subject: i965: fix segfault on low memory conditions When out of memory (in at least one case, triggered by a longrunning memory leak), this code will segfault and crash. By checking for the out-of-memory condition, the system can continue, and will report the out-of-memory error later, a much preferable outcome. --- src/mesa/drivers/dri/i965/brw_wm.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 90d74c2885..cd65f57bbc 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -146,6 +146,13 @@ static void do_wm_prog( struct brw_context *brw, if (c == NULL) { brw->wm.compile_data = calloc(1, sizeof(*brw->wm.compile_data)); c = brw->wm.compile_data; + if (c == NULL) { + /* Ouch - big out of memory problem. Can't continue + * without triggering a segfault, no way to signal, + * so just return. + */ + return; + } } else { memset(c, 0, sizeof(*brw->wm.compile_data)); } -- cgit v1.2.3 From fc6d89145df6fc7a1c2ce648b474c3f203ca87c7 Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 8 May 2009 14:42:47 -0600 Subject: i965: fix memory leak in context/renderbuffer region management A temporary change to the intelMakeCurrent() function to make it work with frame buffer objects causes the static regions associated with the context (the front_region, back_region, and depth_region) to take on an additional reference, with no corresponding release. This causes a memory leak if a program repeatedly creates and destroys contexts. The fix is the corresponding hack, to unreference these regions when the context is deleted, but only if the framebuffer objects are still present and the same regions are still referenced within. Both sets of code have comment blocks referring to each other. --- src/mesa/drivers/dri/intel/intel_context.c | 64 ++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index a6d8729d8f..8b3e50f9b6 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -774,13 +774,64 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->prim.vb_bo = NULL; if (release_texture_heaps) { - /* This share group is about to go away, free our private - * texture object data. + /* Nothing is currently done here to free texture heaps; + * but we're not using the texture heap utilities, so I + * rather think we shouldn't. I've taken a look, and can't + * find any private texture data hanging around anywhere, but + * I'm not yet certain there isn't any at all... */ - if (INTEL_DEBUG & DEBUG_TEXTURE) + /* if (INTEL_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "do something to free texture heaps\n"); + */ } + /* XXX In intelMakeCurrent() below, the context's static regions are + * referenced inside the frame buffer; it's listed as a hack, + * with a comment of "XXX FBO temporary fix-ups!", but + * as long as it's there, we should release the regions here. + * The do/while loop around the block is used to allow the + * "continue" statements inside the block to exit the block, + * to avoid many layers of "if" constructs. + */ + do { + __DRIdrawablePrivate * driDrawPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb; + struct intel_renderbuffer *irbDepth, *irbStencil; + if (!driDrawPriv) { + /* We're already detached from the drawable; exit this block. */ + continue; + } + intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate; + if (!intel_fb) { + /* The frame buffer is already gone; exit this block. */ + continue; + } + irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + /* If the regions of the frame buffer still match the regions + * of the context, release them. If they've changed somehow, + * leave them alone. + */ + if (intel_fb->color_rb[0] && intel_fb->color_rb[0]->region == intel->front_region) { + intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL); + } + if (intel_fb->color_rb[1] && intel_fb->color_rb[1]->region == intel->back_region) { + intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL); + } + + if (irbDepth && irbDepth->region == intel->depth_region) { + intel_renderbuffer_set_region(irbDepth, NULL); + } + /* Usually, the stencil buffer is the same as the depth buffer; + * but they're handled separately in MakeCurrent, so we'll + * handle them separately here. + */ + if (irbStencil && irbStencil->region == intel->depth_region) { + intel_renderbuffer_set_region(irbStencil, NULL); + } + } while (0); + intel_region_release(&intel->front_region); intel_region_release(&intel->back_region); intel_region_release(&intel->depth_region); @@ -789,6 +840,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) /* free the Mesa context */ _mesa_free_context_data(&intel->ctx); + + } } @@ -817,7 +870,10 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (driDrawPriv != driReadPriv) intel_update_renderbuffers(driContextPriv, driReadPriv); } else { - /* XXX FBO temporary fix-ups! */ + /* XXX FBO temporary fix-ups! These are released in + * intelDextroyContext(), above. Changes here should be + * reflected there. + */ /* if the renderbuffers don't have regions, init them from the context */ struct intel_renderbuffer *irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); -- cgit v1.2.3 From 1d112207716774b32c0cc846304c2c50bf40e812 Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 8 May 2009 14:51:11 -0600 Subject: i965: improve debug logging Looking for memory leaks that were causing crashes in my environment in a situation where valgrind would not work, I ended up improving the i965 debug traces so I could better see where the memory was being allocated and where it was going, in the regions and miptrees code, and in the state caches. These traces were specific enough that external scripts could determine what elements were not being released, and where the memory leaks were. I also ended up creating my own backtrace code in intel_regions.c, to determine exactly where regions were being allocated and for what, since valgrind wasn't working. Because it was useful, I left it in, but disabled and compiled out. It can be activated by changing a flag at the top of the file. --- src/mesa/drivers/dri/i965/brw_state_cache.c | 6 ++ src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 6 +- src/mesa/drivers/dri/intel/intel_regions.c | 88 ++++++++++++++++++++++---- 3 files changed, 86 insertions(+), 14 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 320d886c99..e40d7a0416 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -521,6 +521,9 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache) void brw_state_cache_check_size(struct brw_context *brw) { + if (INTEL_DEBUG & DEBUG_STATE) + _mesa_printf("%s (n_items=%d)\n", __FUNCTION__, brw->cache.n_items); + /* un-tuned guess. We've got around 20 state objects for a total of around * 32k, so 1000 of them is around 1.5MB. */ @@ -537,6 +540,9 @@ brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache) { GLuint i; + if (INTEL_DEBUG & DEBUG_STATE) + _mesa_printf("%s\n", __FUNCTION__); + brw_clear_cache(brw, cache); for (i = 0; i < BRW_MAX_CACHE; i++) { dri_bo_unreference(cache->last_bo[i]); diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 6e1e034e53..f3652720ec 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -62,9 +62,10 @@ intel_miptree_create_internal(struct intel_context *intel, GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); - DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); + _mesa_lookup_enum_by_nr(internal_format), + first_level, last_level, mt); mt->target = target_to_target(target); mt->internal_format = internal_format; @@ -89,6 +90,7 @@ intel_miptree_create_internal(struct intel_context *intel, if (!ok) { free(mt); + DBG("%s not okay - returning NULL\n", __FUNCTION__); return NULL; } diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 0aa5b8c02c..534e75efe1 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -52,12 +52,66 @@ #define FILE_DEBUG_FLAG DEBUG_REGION +/* This should be set to the maximum backtrace size desired. + * Set it to 0 to disable backtrace debugging. + */ +#define DEBUG_BACKTRACE_SIZE 0 + +#if DEBUG_BACKTRACE_SIZE == 0 +/* Use the standard debug output */ +#define _DBG(...) DBG(__VA_ARGS__) +#else +/* Use backtracing debug output */ +#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);} + +/* Backtracing debug support */ +#include + +static void +debug_backtrace(void) +{ + void *trace[DEBUG_BACKTRACE_SIZE]; + char **strings = NULL; + int traceSize; + register int i; + + traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE); + strings = backtrace_symbols(trace, traceSize); + if (strings == NULL) { + DBG("no backtrace:"); + return; + } + + /* Spit out all the strings with a colon separator. Ignore + * the first, since we don't really care about the call + * to debug_backtrace() itself. Skip until the final "/" in + * the trace to avoid really long lines. + */ + for (i = 1; i < traceSize; i++) { + char *p = strings[i], *slash = strings[i]; + while (*p) { + if (*p++ == '/') { + slash = p; + } + } + + DBG("%s:", slash); + } + + /* Free up the memory, and we're done */ + free(strings); +} + +#endif + + + /* XXX: Thread safety? */ GLubyte * intel_region_map(struct intel_context *intel, struct intel_region *region) { - DBG("%s\n", __FUNCTION__); + _DBG("%s %p\n", __FUNCTION__, region); if (!region->map_refcount++) { if (region->pbo) intel_region_cow(intel, region); @@ -72,7 +126,7 @@ intel_region_map(struct intel_context *intel, struct intel_region *region) void intel_region_unmap(struct intel_context *intel, struct intel_region *region) { - DBG("%s\n", __FUNCTION__); + _DBG("%s %p\n", __FUNCTION__, region); if (!--region->map_refcount) { dri_bo_unmap(region->buffer); region->map = NULL; @@ -87,10 +141,10 @@ intel_region_alloc_internal(struct intel_context *intel, { struct intel_region *region; - DBG("%s\n", __FUNCTION__); - - if (buffer == NULL) + if (buffer == NULL) { + _DBG("%s <-- NULL\n", __FUNCTION__); return NULL; + } region = calloc(sizeof(*region), 1); region->cpp = cpp; @@ -104,6 +158,7 @@ intel_region_alloc_internal(struct intel_context *intel, region->tiling = I915_TILING_NONE; region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE; + _DBG("%s <-- %p\n", __FUNCTION__, region); return region; } @@ -158,7 +213,7 @@ void intel_region_reference(struct intel_region **dst, struct intel_region *src) { if (src) - DBG("%s %p %d\n", __FUNCTION__, src, src->refcount); + _DBG("%s %p %d\n", __FUNCTION__, src, src->refcount); assert(*dst == NULL); if (src) { @@ -172,10 +227,12 @@ intel_region_release(struct intel_region **region_handle) { struct intel_region *region = *region_handle; - if (region == NULL) + if (region == NULL) { + _DBG("%s NULL\n", __FUNCTION__); return; + } - DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); + _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); ASSERT(region->refcount > 0); region->refcount--; @@ -251,7 +308,7 @@ intel_region_data(struct intel_context *intel, { GLboolean locked = GL_FALSE; - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -293,7 +350,7 @@ intel_region_copy(struct intel_context *intel, GLuint src_offset, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -326,7 +383,7 @@ intel_region_fill(struct intel_context *intel, GLuint dstx, GLuint dsty, GLuint width, GLuint height, GLuint color) { - DBG("%s\n", __FUNCTION__); + _DBG("%s\n", __FUNCTION__); if (intel == NULL) return; @@ -356,6 +413,8 @@ intel_region_attach_pbo(struct intel_context *intel, if (region->pbo == pbo) return; + _DBG("%s %p %p\n", __FUNCTION__, region, pbo); + /* If there is already a pbo attached, break the cow tie now. * Don't call intel_region_release_pbo() as that would * unnecessarily allocate a new buffer we would have to immediately @@ -385,6 +444,7 @@ void intel_region_release_pbo(struct intel_context *intel, struct intel_region *region) { + _DBG("%s %p\n", __FUNCTION__, region); assert(region->buffer == region->pbo->buffer); region->pbo->region = NULL; region->pbo = NULL; @@ -412,7 +472,7 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region) assert(region->cpp * region->pitch * region->height == pbo->Base.Size); - DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); + _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size); /* Now blit from the texture buffer to the new buffer: */ @@ -459,6 +519,10 @@ intel_recreate_static(struct intel_context *intel, if (region == NULL) { region = calloc(sizeof(*region), 1); region->refcount = 1; + _DBG("%s creating new region %p\n", __FUNCTION__, region); + } + else { + _DBG("%s %p\n", __FUNCTION__, region); } if (intel->ctx.Visual.rgbBits == 24) -- cgit v1.2.3