diff options
author | Keith Whitwell <[email protected]> | 2009-02-16 19:50:48 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2009-02-16 19:50:48 +0000 |
commit | 59d54334c96f44ed1d8bf660dc96221362a77d04 (patch) | |
tree | e9ab34e568256bcdc2a88602c47072ab769211e8 /src/mesa/drivers/dri/intel | |
parent | 7c8836e9ef49d938aa55a1c385b95c6371c301f1 (diff) | |
parent | c5c383596ddb26cd75e4b355918ad16915283b59 (diff) |
Merge branch 'master' into gallium-texture-transfer
Conflicts:
src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_drawpixels.c
Diffstat (limited to 'src/mesa/drivers/dri/intel')
26 files changed, 1538 insertions, 1062 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 0fd2f16a8fb..7f2144abd4b 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -25,25 +25,14 @@ * **************************************************************************/ -#include "intel_screen.h" #include "intel_context.h" -#include "intel_blit.h" #include "intel_buffers.h" -#include "intel_chipset.h" -#include "intel_depthstencil.h" #include "intel_fbo.h" #include "intel_regions.h" #include "intel_batchbuffer.h" -#include "intel_reg.h" -#include "main/context.h" #include "main/framebuffer.h" -#include "swrast/swrast.h" -#include "utils.h" #include "drirenderbuffer.h" -#include "vblank.h" -#include "i915_drm.h" -#define FILE_DEBUG_FLAG DEBUG_BLIT /** * XXX move this into a new dri/common/cliprects.c file. @@ -114,7 +103,6 @@ intel_get_cliprects(struct intel_context *intel, int *x_off, int *y_off) { __DRIdrawablePrivate *dPriv = intel->driDrawable; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; if (intel->constant_cliprect) { /* FBO or DRI2 rendering, which can just use the fb's size. */ @@ -143,399 +131,6 @@ intel_get_cliprects(struct intel_context *intel, } } -/** - * This will be called whenever the currently bound window is moved/resized. - * XXX: actually, it seems to NOT be called when the window is only moved (BP). - */ -void -intelWindowMoved(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - - if (!intel->intelScreen->driScrnPriv->dri2.enabled && - intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { - volatile drm_i915_sarea_t *sarea = intel->sarea; - drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, - .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; - drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, - .x2 = sarea->planeA_x + sarea->planeA_w, - .y2 = sarea->planeA_y + sarea->planeA_h }; - drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, - .x2 = sarea->planeB_x + sarea->planeB_w, - .y2 = sarea->planeB_y + sarea->planeB_h }; - GLint areaA = driIntersectArea( drw_rect, planeA_rect ); - GLint areaB = driIntersectArea( drw_rect, planeB_rect ); - GLuint flags = dPriv->vblFlags; - - /* Update vblank info - */ - if (areaB > areaA || (areaA == areaB && areaB > 0)) { - flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; - } else { - flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; - } - - /* Check to see if we changed pipes */ - if (flags != dPriv->vblFlags && dPriv->vblFlags && - !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { - int64_t count; - drmVBlank vbl; - int i; - - /* - * Deal with page flipping - */ - vbl.request.type = DRM_VBLANK_ABSOLUTE; - - if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { - vbl.request.type |= DRM_VBLANK_SECONDARY; - } - - for (i = 0; i < 2; i++) { - if (!intel_fb->color_rb[i] || - (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= - (1<<23)) - continue; - - vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; - drmWaitVBlank(intel->driFd, &vbl); - } - - /* - * Update msc_base from old pipe - */ - driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); - dPriv->msc_base = count; - /* - * Then get new vblank_base and vblSeq values - */ - dPriv->vblFlags = flags; - driGetCurrentVBlank(dPriv); - dPriv->vblank_base = dPriv->vblSeq; - - intel_fb->vbl_waited = dPriv->vblSeq; - - for (i = 0; i < 2; i++) { - if (intel_fb->color_rb[i]) - intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; - } - } - } else { - dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; - } - - /* Update Mesa's notion of window size */ - driUpdateFramebufferSize(ctx, dPriv); - intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ - - /* Update hardware scissor */ - if (ctx->Driver.Scissor != NULL) { - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); - } - - /* Re-calculate viewport related state */ - if (ctx->Driver.DepthRange != NULL) - ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); -} - - - -/* A true meta version of this would be very simple and additionally - * machine independent. Maybe we'll get there one day. - */ -static void -intelClearWithTris(struct intel_context *intel, GLbitfield mask) -{ - GLcontext *ctx = &intel->ctx; - struct gl_framebuffer *fb = ctx->DrawBuffer; - GLuint buf; - - intel->vtbl.install_meta_state(intel); - - /* Back and stencil cliprects are the same. Try and do both - * buffers at once: - */ - if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { - struct intel_region *backRegion = - intel_get_rb_region(fb, BUFFER_BACK_LEFT); - struct intel_region *depthRegion = - intel_get_rb_region(fb, BUFFER_DEPTH); - - intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); - - if (mask & BUFFER_BIT_BACK_LEFT) - intel->vtbl.meta_color_mask(intel, GL_TRUE); - else - intel->vtbl.meta_color_mask(intel, GL_FALSE); - - if (mask & BUFFER_BIT_STENCIL) - intel->vtbl.meta_stencil_replace(intel, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - else - intel->vtbl.meta_no_stencil_write(intel); - - if (mask & BUFFER_BIT_DEPTH) - intel->vtbl.meta_depth_replace(intel); - else - intel->vtbl.meta_no_depth_write(intel); - - intel->vtbl.meta_draw_quad(intel, - fb->_Xmin, - fb->_Xmax, - fb->_Ymin, - fb->_Ymax, - intel->ctx.Depth.Clear, - intel->ClearColor8888, - 0, 0, 0, 0); /* texcoords */ - - mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); - } - - /* clear the remaining (color) renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { - const GLuint bufBit = 1 << buf; - if (mask & bufBit) { - struct intel_renderbuffer *irbColor = - intel_renderbuffer(fb->Attachment[buf].Renderbuffer); - - ASSERT(irbColor); - - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_TRUE); - intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); - - intel->vtbl.meta_draw_quad(intel, - fb->_Xmin, - fb->_Xmax, - fb->_Ymin, - fb->_Ymax, - 0, intel->ClearColor8888, - 0, 0, 0, 0); /* texcoords */ - - mask &= ~bufBit; - } - } - - intel->vtbl.leave_meta_state(intel); -} - -static const char *buffer_names[] = { - [BUFFER_FRONT_LEFT] = "front", - [BUFFER_BACK_LEFT] = "back", - [BUFFER_FRONT_RIGHT] = "front right", - [BUFFER_BACK_RIGHT] = "back right", - [BUFFER_AUX0] = "aux0", - [BUFFER_AUX1] = "aux1", - [BUFFER_AUX2] = "aux2", - [BUFFER_AUX3] = "aux3", - [BUFFER_DEPTH] = "depth", - [BUFFER_STENCIL] = "stencil", - [BUFFER_ACCUM] = "accum", - [BUFFER_COLOR0] = "color0", - [BUFFER_COLOR1] = "color1", - [BUFFER_COLOR2] = "color2", - [BUFFER_COLOR3] = "color3", - [BUFFER_COLOR4] = "color4", - [BUFFER_COLOR5] = "color5", - [BUFFER_COLOR6] = "color6", - [BUFFER_COLOR7] = "color7", -}; - -/** - * Called by ctx->Driver.Clear. - */ -static void -intelClear(GLcontext *ctx, GLbitfield mask) -{ - struct intel_context *intel = intel_context(ctx); - const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); - GLbitfield tri_mask = 0; - GLbitfield blit_mask = 0; - GLbitfield swrast_mask = 0; - struct gl_framebuffer *fb = ctx->DrawBuffer; - GLuint i; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* HW color buffers (front, back, aux, generic FBO, etc) */ - if (colorMask == ~0) { - /* clear all R,G,B,A */ - /* XXX FBO: need to check if colorbuffers are software RBOs! */ - blit_mask |= (mask & BUFFER_BITS_COLOR); - } - else { - /* glColorMask in effect */ - tri_mask |= (mask & BUFFER_BITS_COLOR); - } - - /* HW stencil */ - if (mask & BUFFER_BIT_STENCIL) { - const struct intel_region *stencilRegion - = intel_get_rb_region(fb, BUFFER_STENCIL); - if (stencilRegion) { - /* have hw stencil */ - if (IS_965(intel->intelScreen->deviceID) || - (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { - /* We have to use the 3D engine if we're clearing a partial mask - * of the stencil buffer, or if we're on a 965 which has a tiled - * depth/stencil buffer in a layout we can't blit to. - */ - tri_mask |= BUFFER_BIT_STENCIL; - } - else { - /* clearing all stencil bits, use blitting */ - blit_mask |= BUFFER_BIT_STENCIL; - } - } - } - - /* HW depth */ - if (mask & BUFFER_BIT_DEPTH) { - /* clear depth with whatever method is used for stencil (see above) */ - if (IS_965(intel->intelScreen->deviceID) || - tri_mask & BUFFER_BIT_STENCIL) - tri_mask |= BUFFER_BIT_DEPTH; - else - blit_mask |= BUFFER_BIT_DEPTH; - } - - /* SW fallback clearing */ - swrast_mask = mask & ~tri_mask & ~blit_mask; - - for (i = 0; i < BUFFER_COUNT; i++) { - GLuint bufBit = 1 << i; - if ((blit_mask | tri_mask) & bufBit) { - if (!fb->Attachment[i].Renderbuffer->ClassID) { - blit_mask &= ~bufBit; - tri_mask &= ~bufBit; - swrast_mask |= bufBit; - } - } - } - - if (blit_mask) { - if (INTEL_DEBUG & DEBUG_BLIT) { - DBG("blit clear:"); - for (i = 0; i < BUFFER_COUNT; i++) { - if (blit_mask & (1 << i)) - DBG(" %s", buffer_names[i]); - } - DBG("\n"); - } - intelClearWithBlit(ctx, blit_mask); - } - - if (tri_mask) { - if (INTEL_DEBUG & DEBUG_BLIT) { - DBG("tri clear:"); - for (i = 0; i < BUFFER_COUNT; i++) { - if (tri_mask & (1 << i)) - DBG(" %s", buffer_names[i]); - } - DBG("\n"); - } - intelClearWithTris(intel, tri_mask); - } - - if (swrast_mask) { - if (INTEL_DEBUG & DEBUG_BLIT) { - DBG("swrast clear:"); - for (i = 0; i < BUFFER_COUNT; i++) { - if (swrast_mask & (1 << i)) - DBG(" %s", buffer_names[i]); - } - DBG("\n"); - } - _swrast_Clear(ctx, swrast_mask); - } -} - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel; - - if (ctx == NULL) - return; - - intel = intel_context(ctx); - - if (ctx->Visual.doubleBufferMode) { - GLboolean missed_target; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - int64_t ust; - - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - - /* - * The old swapping ioctl was incredibly racy, just wait for vblank - * and do the swap ourselves. - */ - driWaitForVBlank(dPriv, &missed_target); - - /* - * Update each buffer's vbl_pending so we don't get too out of - * sync - */ - intel_get_renderbuffer(&intel_fb->Base, - BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq; - intel_get_renderbuffer(&intel_fb->Base, - BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; - - intelCopyBuffer(dPriv, NULL); - - intel_fb->swap_count++; - (*psp->systemTime->getUST) (&ust); - if (missed_target) { - intel_fb->swap_missed_count++; - intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; - } - - intel_fb->swap_ust = ust; - } - drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE); - - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} - -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - struct intel_context *intel = - (struct intel_context *) dPriv->driContextPriv->driverPrivate; - GLcontext *ctx = &intel->ctx; - - if (ctx->Visual.doubleBufferMode) { - drm_clip_rect_t rect; - rect.x1 = x + dPriv->x; - rect.y1 = (dPriv->h - y - h) + dPriv->y; - rect.x2 = rect.x1 + w; - rect.y2 = rect.y1 + h; - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - intelCopyBuffer(dPriv, &rect); - } - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} - /** * Update the hardware state for drawing into a window or framebuffer object. @@ -559,7 +154,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) return; } - /* Do this here, note core Mesa, since this function is called from + /* 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)) { @@ -577,9 +172,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) return; } - if (fb->Name) - intel_validate_paired_depth_stencil(ctx, fb); - /* * How many color buffers are we drawing into? */ @@ -587,7 +179,8 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* writing to 0 */ colorRegions[0] = NULL; intel->constant_cliprect = GL_TRUE; - } else if (fb->_NumColorDrawBuffers > 1) { + } + else if (fb->_NumColorDrawBuffers > 1) { int i; struct intel_renderbuffer *irb; @@ -626,14 +219,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) } } - /* Update culling direction which changes depending on the - * orientation of the buffer: - */ - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - else - ctx->NewState |= _NEW_POLYGON; - if (!colorRegions[0]) { FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); } @@ -665,20 +250,13 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /*** *** Stencil buffer *** This can only be hardware accelerated if we're using a - *** combined DEPTH_STENCIL buffer (for now anyway). + *** combined DEPTH_STENCIL buffer. ***/ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); if (irbStencil && irbStencil->region) { ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - if (ctx->Driver.Enable != NULL) - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - else - ctx->NewState |= _NEW_STENCIL; - if (!depthRegion) - depthRegion = irbStencil->region; } else { FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); @@ -687,37 +265,30 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) else { /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - if (ctx->Driver.Enable != NULL) - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - else - ctx->NewState |= _NEW_STENCIL; } /* - * Update depth test state + * Update depth and stencil test state */ if (ctx->Driver.Enable) { - if (ctx->Depth.Test && fb->Visual.depthBits > 0) { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); - } else { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); - } - } else { - ctx->NewState |= _NEW_DEPTH; + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, + (ctx->Depth.Test && fb->Visual.depthBits > 0)); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, + (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); + } + else { + ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); } intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, - fb->_NumColorDrawBuffers); + fb->_NumColorDrawBuffers); /* update viewport since it depends on window size */ - if (ctx->Driver.Viewport) { - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); - } else { - ctx->NewState |= _NEW_VIEWPORT; - } - +#ifdef I915 + intelCalcViewport(ctx); +#else + ctx->NewState |= _NEW_VIEWPORT; +#endif /* Set state we know depends on drawable parameters: */ if (ctx->Driver.Scissor) @@ -729,6 +300,14 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; } @@ -759,7 +338,6 @@ intelReadBuffer(GLcontext * ctx, GLenum mode) void intelInitBufferFuncs(struct dd_function_table *functions) { - functions->Clear = intelClear; functions->DrawBuffer = intelDrawBuffer; functions->ReadBuffer = intelReadBuffer; } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.h b/src/mesa/drivers/dri/intel/intel_buffers.h index 0be1cee0914..6069d38e9eb 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.h +++ b/src/mesa/drivers/dri/intel/intel_buffers.h @@ -45,10 +45,6 @@ extern struct intel_region *intel_readbuf_region(struct intel_context *intel); extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelWindowMoved(struct intel_context *intel); - extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); extern void intelInitBufferFuncs(struct dd_function_table *functions); @@ -57,5 +53,8 @@ void intel_get_cliprects(struct intel_context *intel, struct drm_clip_rect **cliprects, unsigned int *num_cliprects, int *x_off, int *y_off); +#ifdef I915 +void intelCalcViewport(GLcontext * ctx); +#endif #endif /* INTEL_BUFFERS_H */ diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c new file mode 100644 index 00000000000..b2291363164 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -0,0 +1,376 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "main/enums.h" +#include "main/image.h" +#include "main/mtypes.h" +#include "main/attrib.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/macros.h" +#include "main/matrix.h" +#include "main/texstate.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/varray.h" +#include "glapi/dispatch.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_blit.h" +#include "intel_chipset.h" +#include "intel_clear.h" +#include "intel_fbo.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +/** + * Perform glClear where mask contains only color, depth, and/or stencil. + * + * The implementation is based on calling into Mesa to set GL state and + * performing normal triangle rendering. The intent of this path is to + * have as generic a path as possible, so that any driver could make use of + * it. + */ +void +intel_clear_tris(GLcontext *ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + GLfloat vertices[4][3]; + GLfloat color[4][4]; + GLfloat dst_z; + struct gl_framebuffer *fb = ctx->DrawBuffer; + int i; + GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; + GLboolean saved_shader_program = 0; + unsigned int saved_active_texture; + + assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT | + BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); + + _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | + GL_CURRENT_BIT | + GL_DEPTH_BUFFER_BIT | + GL_ENABLE_BIT | + GL_STENCIL_BUFFER_BIT | + GL_TRANSFORM_BIT | + GL_CURRENT_BIT); + _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + saved_active_texture = ctx->Texture.CurrentUnit; + + /* Disable existing GL state we don't want to apply to a clear. */ + _mesa_Disable(GL_ALPHA_TEST); + _mesa_Disable(GL_BLEND); + _mesa_Disable(GL_CULL_FACE); + _mesa_Disable(GL_FOG); + _mesa_Disable(GL_POLYGON_SMOOTH); + _mesa_Disable(GL_POLYGON_STIPPLE); + _mesa_Disable(GL_POLYGON_OFFSET_FILL); + _mesa_Disable(GL_LIGHTING); + _mesa_Disable(GL_CLIP_PLANE0); + _mesa_Disable(GL_CLIP_PLANE1); + _mesa_Disable(GL_CLIP_PLANE2); + _mesa_Disable(GL_CLIP_PLANE3); + _mesa_Disable(GL_CLIP_PLANE4); + _mesa_Disable(GL_CLIP_PLANE5); + if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { + saved_fp_enable = GL_TRUE; + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { + saved_vp_enable = GL_TRUE; + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); + } + if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { + saved_shader_program = ctx->Shader.CurrentProgram->Name; + _mesa_UseProgramObjectARB(0); + } + + if (ctx->Texture._EnabledUnits != 0) { + int i; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + i); + _mesa_Disable(GL_TEXTURE_1D); + _mesa_Disable(GL_TEXTURE_2D); + _mesa_Disable(GL_TEXTURE_3D); + if (ctx->Extensions.ARB_texture_cube_map) + _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); + if (ctx->Extensions.NV_texture_rectangle) + _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); + if (ctx->Extensions.MESA_texture_array) { + _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); + _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); + } + } + } + + intel_meta_set_passthrough_transform(intel); + + for (i = 0; i < 4; i++) { + color[i][0] = ctx->Color.ClearColor[0]; + color[i][1] = ctx->Color.ClearColor[1]; + color[i][2] = ctx->Color.ClearColor[2]; + color[i][3] = ctx->Color.ClearColor[3]; + } + + /* convert clear Z from [0,1] to NDC coord in [-1,1] */ + dst_z = -1.0 + 2.0 * ctx->Depth.Clear; + + /* Prepare the vertices, which are the same regardless of which buffer we're + * drawing to. + */ + vertices[0][0] = fb->_Xmin; + vertices[0][1] = fb->_Ymin; + vertices[0][2] = dst_z; + vertices[1][0] = fb->_Xmax; + vertices[1][1] = fb->_Ymin; + vertices[1][2] = dst_z; + vertices[2][0] = fb->_Xmax; + vertices[2][1] = fb->_Ymax; + vertices[2][2] = dst_z; + vertices[3][0] = fb->_Xmin; + vertices[3][1] = fb->_Ymax; + vertices[3][2] = dst_z; + + _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color); + _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices); + _mesa_Enable(GL_COLOR_ARRAY); + _mesa_Enable(GL_VERTEX_ARRAY); + + while (mask != 0) { + GLuint this_mask = 0; + + if (mask & BUFFER_BIT_BACK_LEFT) + this_mask = BUFFER_BIT_BACK_LEFT; + else if (mask & BUFFER_BIT_FRONT_LEFT) + this_mask = BUFFER_BIT_FRONT_LEFT; + + /* Clear depth/stencil in the same pass as color. */ + this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); + + /* Select the current color buffer and use the color write mask if + * we have one, otherwise don't write any color channels. + */ + if (this_mask & BUFFER_BIT_FRONT_LEFT) + _mesa_DrawBuffer(GL_FRONT_LEFT); + else if (this_mask & BUFFER_BIT_BACK_LEFT) + _mesa_DrawBuffer(GL_BACK_LEFT); + else + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + /* Control writing of the depth clear value to depth. */ + if (this_mask & BUFFER_BIT_DEPTH) { + _mesa_DepthFunc(GL_ALWAYS); + _mesa_Enable(GL_DEPTH_TEST); + } else { + _mesa_Disable(GL_DEPTH_TEST); + _mesa_DepthMask(GL_FALSE); + } + + /* Control writing of the stencil clear value to stencil. */ + if (this_mask & BUFFER_BIT_STENCIL) { + _mesa_Enable(GL_STENCIL_TEST); + _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear, + ctx->Stencil.WriteMask[0]); + } else { + _mesa_Disable(GL_STENCIL_TEST); + } + + CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); + + mask &= ~this_mask; + } + + intel_meta_restore_transform(intel); + + _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); + if (saved_fp_enable) + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); + if (saved_vp_enable) + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); + + if (saved_shader_program) + _mesa_UseProgramObjectARB(saved_shader_program); + + _mesa_PopClientAttrib(); + _mesa_PopAttrib(); +} + +static const char *buffer_names[] = { + [BUFFER_FRONT_LEFT] = "front", + [BUFFER_BACK_LEFT] = "back", + [BUFFER_FRONT_RIGHT] = "front right", + [BUFFER_BACK_RIGHT] = "back right", + [BUFFER_AUX0] = "aux0", + [BUFFER_AUX1] = "aux1", + [BUFFER_AUX2] = "aux2", + [BUFFER_AUX3] = "aux3", + [BUFFER_DEPTH] = "depth", + [BUFFER_STENCIL] = "stencil", + [BUFFER_ACCUM] = "accum", + [BUFFER_COLOR0] = "color0", + [BUFFER_COLOR1] = "color1", + [BUFFER_COLOR2] = "color2", + [BUFFER_COLOR3] = "color3", + [BUFFER_COLOR4] = "color4", + [BUFFER_COLOR5] = "color5", + [BUFFER_COLOR6] = "color6", + [BUFFER_COLOR7] = "color7", +}; + +/** + * Called by ctx->Driver.Clear. + */ +static void +intelClear(GLcontext *ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + GLbitfield tri_mask = 0; + GLbitfield blit_mask = 0; + GLbitfield swrast_mask = 0; + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint i; + + if (0) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* HW color buffers (front, back, aux, generic FBO, etc) */ + if (colorMask == ~0) { + /* clear all R,G,B,A */ + /* XXX FBO: need to check if colorbuffers are software RBOs! */ + blit_mask |= (mask & BUFFER_BITS_COLOR); + } + else { + /* glColorMask in effect */ + tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)); + } + + /* HW stencil */ + if (mask & BUFFER_BIT_STENCIL) { + const struct intel_region *stencilRegion + = intel_get_rb_region(fb, BUFFER_STENCIL); + if (stencilRegion) { + /* have hw stencil */ + if (IS_965(intel->intelScreen->deviceID) || + (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { + /* We have to use the 3D engine if we're clearing a partial mask + * of the stencil buffer, or if we're on a 965 which has a tiled + * depth/stencil buffer in a layout we can't blit to. + */ + tri_mask |= BUFFER_BIT_STENCIL; + } + else { + /* clearing all stencil bits, use blitting */ + blit_mask |= BUFFER_BIT_STENCIL; + } + } + } + + /* HW depth */ + if (mask & BUFFER_BIT_DEPTH) { + /* clear depth with whatever method is used for stencil (see above) */ + if (IS_965(intel->intelScreen->deviceID) || + tri_mask & BUFFER_BIT_STENCIL) + tri_mask |= BUFFER_BIT_DEPTH; + else + blit_mask |= BUFFER_BIT_DEPTH; + } + + /* If we're doing a tri pass for depth/stencil, include a likely color + * buffer with it. + */ + if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { + tri_mask |= blit_mask & BUFFER_BIT_BACK_LEFT; + blit_mask &= ~BUFFER_BIT_BACK_LEFT; + } + + /* SW fallback clearing */ + swrast_mask = mask & ~tri_mask & ~blit_mask; + + for (i = 0; i < BUFFER_COUNT; i++) { + GLuint bufBit = 1 << i; + if ((blit_mask | tri_mask) & bufBit) { + if (!fb->Attachment[i].Renderbuffer->ClassID) { + blit_mask &= ~bufBit; + tri_mask &= ~bufBit; + swrast_mask |= bufBit; + } + } + } + + if (blit_mask) { + if (INTEL_DEBUG & DEBUG_BLIT) { + DBG("blit clear:"); + for (i = 0; i < BUFFER_COUNT; i++) { + if (blit_mask & (1 << i)) + DBG(" %s", buffer_names[i]); + } + DBG("\n"); + } + intelClearWithBlit(ctx, blit_mask); + } + + if (tri_mask) { + if (INTEL_DEBUG & DEBUG_BLIT) { + DBG("tri clear:"); + for (i = 0; i < BUFFER_COUNT; i++) { + if (tri_mask & (1 << i)) + DBG(" %s", buffer_names[i]); + } + DBG("\n"); + } + intel_clear_tris(ctx, tri_mask); + } + + if (swrast_mask) { + if (INTEL_DEBUG & DEBUG_BLIT) { + DBG("swrast clear:"); + for (i = 0; i < BUFFER_COUNT; i++) { + if (swrast_mask & (1 << i)) + DBG(" %s", buffer_names[i]); + } + DBG("\n"); + } + _swrast_Clear(ctx, swrast_mask); + } +} + + +void +intelInitClearFuncs(struct dd_function_table *functions) +{ + functions->Clear = intelClear; +} diff --git a/src/mesa/drivers/dri/intel/intel_clear.h b/src/mesa/drivers/dri/intel/intel_clear.h new file mode 100644 index 00000000000..7fd6b310a9d --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_clear.h @@ -0,0 +1,38 @@ + +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#ifndef INTEL_CLEAR_H +#define INTEL_CLEAR_H + +struct dd_function_table; + +extern void +intelInitClearFuncs(struct dd_function_table *functions); + + +#endif /* INTEL_CLEAR_H */ diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index c4a24d73972..d7ccfa06058 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -28,8 +28,6 @@ #include "main/glheader.h" #include "main/context.h" -#include "main/matrix.h" -#include "main/simple_list.h" #include "main/extensions.h" #include "main/framebuffer.h" #include "main/imports.h" @@ -38,66 +36,40 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" - -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - #include "drivers/common/driverfuncs.h" -#include "intel_screen.h" - #include "i830_dri.h" #include "intel_chipset.h" #include "intel_buffers.h" #include "intel_tex.h" #include "intel_batchbuffer.h" -#include "intel_blit.h" +#include "intel_clear.h" +#include "intel_extensions.h" #include "intel_pixel.h" #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" #include "intel_decode.h" #include "intel_bufmgr.h" +#include "intel_screen.h" +#include "intel_swapbuffers.h" #include "drirenderbuffer.h" #include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ + + #ifndef INTEL_DEBUG int INTEL_DEBUG = (0); #endif -#define need_GL_ARB_multisample -#define need_GL_ARB_occlusion_query -#define need_GL_ARB_point_parameters -#define need_GL_ARB_shader_objects -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_vertex_shader -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_point_parameters -#define need_GL_EXT_secondary_color -#define need_GL_ATI_separate_stencil -#define need_GL_NV_point_sprite -#define need_GL_NV_vertex_program -#define need_GL_VERSION_2_0 -#define need_GL_VERSION_2_1 - -#include "extension_helper.h" #define DRIVER_DATE "20090114" #define DRIVER_DATE_GEM "GEM " DRIVER_DATE + static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -282,6 +254,9 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) return; } + if (rb == NULL) + continue; + if (rb->region) { dri_bo_flink(rb->region->buffer, &name); if (name == buffers[i].name) @@ -340,112 +315,6 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) ctx->Driver.Viewport = old_viewport; } -/** - * Extension strings exported by the intel driver. - * - * Extensions supported by all chips supported by i830_dri, i915_dri, or - * i965_dri. - */ -static const struct dri_extension card_extensions[] = { - { "GL_ARB_multisample", GL_ARB_multisample_functions }, - { "GL_ARB_multitexture", NULL }, - { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, - { "GL_ARB_texture_border_clamp", NULL }, - { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, - { "GL_ARB_texture_cube_map", NULL }, - { "GL_ARB_texture_env_add", NULL }, - { "GL_ARB_texture_env_combine", NULL }, - { "GL_ARB_texture_env_crossbar", NULL }, - { "GL_ARB_texture_env_dot3", NULL }, - { "GL_ARB_texture_mirrored_repeat", NULL }, - { "GL_ARB_texture_rectangle", NULL }, - { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, - { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, - { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, - { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, - { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, - { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, - { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, - { "GL_EXT_blend_logic_op", NULL }, - { "GL_EXT_blend_subtract", NULL }, - { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions }, - { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, - { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions }, - { "GL_EXT_packed_depth_stencil", NULL }, - { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, - { "GL_EXT_stencil_wrap", NULL }, - { "GL_EXT_texture_edge_clamp", NULL }, - { "GL_EXT_texture_env_combine", NULL }, - { "GL_EXT_texture_env_dot3", NULL }, - { "GL_EXT_texture_filter_anisotropic", NULL }, - { "GL_EXT_texture_lod_bias", NULL }, - { "GL_3DFX_texture_compression_FXT1", NULL }, - { "GL_APPLE_client_storage", NULL }, - { "GL_MESA_pack_invert", NULL }, - { "GL_MESA_ycbcr_texture", NULL }, - { "GL_NV_blend_square", NULL }, - { "GL_NV_point_sprite", GL_NV_point_sprite_functions }, - { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, - { "GL_NV_vertex_program1_1", NULL }, - { "GL_SGIS_generate_mipmap", NULL }, - { NULL, NULL } -}; - -static const struct dri_extension brw_extensions[] = { - { "GL_ARB_depth_texture", NULL }, - { "GL_ARB_draw_buffers", NULL }, - { "GL_ARB_fragment_program", NULL }, - { "GL_ARB_fragment_program_shadow", NULL }, - { "GL_ARB_fragment_shader", NULL }, - { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, - { "GL_ARB_point_sprite", NULL }, - { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, - { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, -#if 0 - /* Support for GLSL 1.20 is currently broken in core Mesa. - */ - { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, -#endif - { "GL_ARB_shadow", NULL }, - { "GL_ARB_texture_non_power_of_two", NULL }, - { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, - { "GL_EXT_shadow_funcs", NULL }, - { "GL_EXT_texture_sRGB", NULL }, - { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions }, - { "GL_ATI_texture_env_combine3", NULL }, - { NULL, NULL } -}; - -static const struct dri_extension arb_oq_extensions[] = { - { NULL, NULL } -}; - -static const struct dri_extension ttm_extensions[] = { - { "GL_ARB_pixel_buffer_object", NULL }, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, - { NULL, NULL } -}; - -/** - * Initializes potential list of extensions if ctx == NULL, or actually enables - * extensions for a context. - */ -void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) -{ - struct intel_context *intel = ctx?intel_context(ctx):NULL; - - /* Disable imaging extension until convolution is working in teximage paths. - */ - enable_imaging = GL_FALSE; - - driInitExtensions(ctx, card_extensions, enable_imaging); - - if (intel == NULL || intel->ttm) - driInitExtensions(ctx, ttm_extensions, GL_FALSE); - - if (intel == NULL || IS_965(intel->intelScreen->deviceID)) - driInitExtensions(ctx, brw_extensions, GL_FALSE); -} static const struct dri_debug_control debug_control[] = { { "tex", DEBUG_TEXTURE}, @@ -496,9 +365,8 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) intel->vtbl.invalidate_state( intel, new_state ); } - -void -intelFlush(GLcontext * ctx) +static void +intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) { struct intel_context *intel = intel_context(ctx); @@ -512,13 +380,26 @@ intelFlush(GLcontext * ctx) * lands onscreen in a timely manner, even if the X Server doesn't trigger * a flush for us. */ - intel_batchbuffer_emit_mi_flush(intel->batch); + if (needs_mi_flush) + intel_batchbuffer_emit_mi_flush(intel->batch); if (intel->batch->map != intel->batch->ptr) intel_batchbuffer_flush(intel->batch); } void +intelFlush(GLcontext * ctx) +{ + intel_flush(ctx, GL_FALSE); +} + +static void +intel_glFlush(GLcontext *ctx) +{ + intel_flush(ctx, GL_TRUE); +} + +void intelFinish(GLcontext * ctx) { struct gl_framebuffer *fb = ctx->DrawBuffer; @@ -544,7 +425,7 @@ intelInitDriverFunctions(struct dd_function_table *functions) { _mesa_init_driver_functions(functions); - functions->Flush = intelFlush; + functions->Flush = intel_glFlush; functions->Finish = intelFinish; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; @@ -556,6 +437,7 @@ intelInitDriverFunctions(struct dd_function_table *functions) intelInitTextureFuncs(functions); intelInitStateFuncs(functions); + intelInitClearFuncs(functions); intelInitBufferFuncs(functions); intelInitPixelFuncs(functions); } @@ -858,6 +740,11 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; + /* Prevent error printf if one crtc is disabled, this will + * be properly calculated in intelWindowMoved() next. + */ + driDrawPriv->vblFlags = intelFixupVblank(intel, driDrawPriv); + (*psp->systemTime->getUST) (&intel_fb->swap_ust); driDrawableInitVBlank(driDrawPriv); intel_fb->vbl_waited = driDrawPriv->vblSeq; diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index 348da347ddc..18dc43c4a42 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -210,7 +210,6 @@ struct intel_context char *prevLockFile; int prevLockLine; - GLubyte clear_chan[4]; GLuint ClearColor565; GLuint ClearColor8888; @@ -438,7 +437,6 @@ extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); extern void intelInitDriverFunctions(struct dd_function_table *functions); -extern void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); /* ================================================================ diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c index 5f90ca22ece..136221c37fc 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.c +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -87,27 +87,28 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) struct { uint32_t opcode; + int len_mask; int min_len; int max_len; char *name; } opcodes_mi[] = { - { 0x08, 1, 1, "MI_ARB_ON_OFF" }, - { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, - { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, - { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, - { 0x04, 1, 1, "MI_FLUSH" }, - { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, - { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, - { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, - { 0x00, 1, 1, "MI_NOOP" }, - { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, - { 0x07, 1, 1, "MI_REPORT_HEAD" }, - { 0x18, 2, 2, "MI_SET_CONTEXT" }, - { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, - { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, - { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, - { 0x02, 1, 1, "MI_USER_INTERRUPT" }, - { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 0, 1, 1, "MI_FLUSH" }, + { 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 0, 1, 1, "MI_NOOP" }, + { 0x11, 0x3f, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 0, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 0x3f, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 0x3f, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 0x3f, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 0x3f, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 0, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" }, }; @@ -118,12 +119,14 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); if (opcodes_mi[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; + len = (data[0] & opcodes_mi[opcode].len_mask) + 2; if (len < opcodes_mi[opcode].min_len || len > opcodes_mi[opcode].max_len) { - fprintf(out, "Bad length in %s\n", - opcodes_mi[opcode].name); + fprintf(out, "Bad length (%d) in %s, [%d, %d]\n", + len, opcodes_mi[opcode].name, + opcodes_mi[opcode].min_len, + opcodes_mi[opcode].max_len); } } @@ -932,7 +935,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); len = (data[0] & 0x000000ff) + 2; - i = 1; + i = 2; for (c = 0; c <= 31; c++) { if (data[1] & (1 << c)) { if (i + 4 >= count) @@ -952,7 +955,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i } } if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_CONSTANTS\n"); (*failures)++; } return len; diff --git a/src/mesa/drivers/dri/intel/intel_depthstencil.c b/src/mesa/drivers/dri/intel/intel_depthstencil.c deleted file mode 100644 index 354b3bf0d70..00000000000 --- a/src/mesa/drivers/dri/intel/intel_depthstencil.c +++ /dev/null @@ -1,261 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN GRAPHICS 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. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/depthstencil.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" -#include "main/hash.h" -#include "main/mtypes.h" -#include "main/renderbuffer.h" - -#include "intel_context.h" -#include "intel_fbo.h" -#include "intel_depthstencil.h" -#include "intel_regions.h" -#include "intel_span.h" - -/** - * The GL_EXT_framebuffer_object allows the user to create their own - * framebuffer objects consisting of color renderbuffers (0 or more), - * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). - * - * The spec considers depth and stencil renderbuffers to be totally independent - * buffers. In reality, most graphics hardware today uses a combined - * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). - * - * This causes difficulty because the user may create some number of depth - * renderbuffers and some number of stencil renderbuffers and bind them - * together in framebuffers in any combination. - * - * This code manages all that. - * - * 1. Depth renderbuffers are always allocated in hardware as 32bpp - * GL_DEPTH24_STENCIL8 buffers. - * - * 2. Stencil renderbuffers are initially allocated in software as 8bpp - * GL_STENCIL_INDEX8 buffers. - * - * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth - * fields (respectively) to indicate if the buffer's currently paired - * with another stencil or depth buffer (respectively). - * - * 4. When a depth and stencil buffer are initially both attached to the - * current framebuffer, we merge the stencil buffer values into the - * depth buffer (really a depth+stencil buffer). The then hardware uses - * the combined buffer. - * - * 5. Whenever a depth or stencil buffer is reallocated (with - * glRenderbufferStorage) we undo the pairing and copy the stencil values - * from the combined depth/stencil buffer back to the stencil-only buffer. - * - * 6. We also undo the pairing when we find a change in buffer bindings. - * - * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we - * just use the combined depth/stencil buffer and ignore the stencil values. - * - * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have - * to promote the 8bpp software stencil buffer to a 32bpp hardware - * depth+stencil buffer. - * - */ - -/** - * Undo the pairing/interleaving between depth and stencil buffers. - * irb should be a depth/stencil or stencil renderbuffer. - */ -void -intel_unpair_depth_stencil(GLcontext *ctx, struct intel_renderbuffer *irb) -{ - struct intel_context *intel = intel_context(ctx); - struct gl_renderbuffer *rb = &irb->Base; - - if (irb->PairedStencil) { - /* irb is a depth/stencil buffer */ - struct gl_renderbuffer *stencilRb; - struct intel_renderbuffer *stencilIrb; - - ASSERT(rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil); - stencilIrb = intel_renderbuffer(stencilRb); - if (stencilIrb) { - /* need to extract stencil values from the depth buffer */ - ASSERT(stencilIrb->PairedDepth == rb->Name); - intel_renderbuffer_map(intel, rb); - intel_renderbuffer_map(intel, stencilRb); -#if 0 - /* disable for now */ - _mesa_extract_stencil(ctx, rb, stencilRb); -#endif - intel_renderbuffer_unmap(intel, stencilRb); - intel_renderbuffer_unmap(intel, rb); - stencilIrb->PairedDepth = 0; - } - irb->PairedStencil = 0; - } - else if (irb->PairedDepth) { - /* irb is a stencil buffer */ - struct gl_renderbuffer *depthRb; - struct intel_renderbuffer *depthIrb; - - ASSERT(rb->_ActualFormat == GL_STENCIL_INDEX8_EXT || - rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth); - depthIrb = intel_renderbuffer(depthRb); - if (depthIrb) { - /* need to extract stencil values from the depth buffer */ - ASSERT(depthIrb->PairedStencil == rb->Name); - intel_renderbuffer_map(intel, rb); - intel_renderbuffer_map(intel, depthRb); -#if 0 - /* disable for now */ - _mesa_extract_stencil(ctx, depthRb, rb); -#endif - intel_renderbuffer_unmap(intel, depthRb); - intel_renderbuffer_unmap(intel, rb); - depthIrb->PairedStencil = 0; - } - irb->PairedDepth = 0; - } - else { - _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing"); - } - - ASSERT(irb->PairedStencil == 0); - ASSERT(irb->PairedDepth == 0); -} - - -/** - * Examine the depth and stencil renderbuffers which are attached to the - * framebuffer. If both depth and stencil are attached, make sure that the - * renderbuffers are 'paired' (combined). If only depth or only stencil is - * attached, undo any previous pairing. - * - * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments - * change, for example). - */ -void -intel_validate_paired_depth_stencil(GLcontext * ctx, - struct gl_framebuffer *fb) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_renderbuffer *depthRb, *stencilRb; - - depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); - stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); - - if (depthRb && stencilRb) { - if (depthRb == stencilRb) { - /* Using a user-created combined depth/stencil buffer. - * Nothing to do. - */ - ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - } - else { - /* Separate depth/stencil buffers, need to interleave now */ - ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT || - depthRb->Base._BaseFormat == GL_DEPTH_STENCIL); - ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX || - stencilRb->Base._BaseFormat == GL_DEPTH_STENCIL); - - /* may need to interleave depth/stencil now */ - if (depthRb->PairedStencil == stencilRb->Base.Name) { - /* OK, the depth and stencil buffers are already interleaved */ - ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); - } - else { - /* need to setup new pairing/interleaving */ - if (depthRb->PairedStencil) { - intel_unpair_depth_stencil(ctx, depthRb); - } - if (stencilRb->PairedDepth) { - intel_unpair_depth_stencil(ctx, stencilRb); - } - - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || - stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - /* establish new pairing: interleave stencil into depth buffer */ - intel_renderbuffer_map(intel, &depthRb->Base); - intel_renderbuffer_map(intel, &stencilRb->Base); - _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); - intel_renderbuffer_unmap(intel, &stencilRb->Base); - intel_renderbuffer_unmap(intel, &depthRb->Base); - depthRb->PairedStencil = stencilRb->Base.Name; - stencilRb->PairedDepth = depthRb->Base.Name; - } - - } - } - else if (depthRb) { - /* Depth buffer but no stencil buffer. - * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. - */ - /* can't assert this until storage is allocated: - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - */ - /* intel_undo any previous pairing */ - if (depthRb->PairedStencil) { - intel_unpair_depth_stencil(ctx, depthRb); - } - } - else if (stencilRb) { - /* Stencil buffer but no depth buffer. - * Since h/w doesn't typically support just 8bpp stencil w/out Z, - * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. - */ - /* undo any previous pairing */ - if (stencilRb->PairedDepth) { - intel_unpair_depth_stencil(ctx, stencilRb); - } - if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { - /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ - _mesa_promote_stencil(ctx, &stencilRb->Base); - ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - } - } - - /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ - _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); - if (depthRb && depthRb->PairedStencil) - _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); - else - _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); - - - /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer - * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer - * if present. - */ -} diff --git a/src/mesa/drivers/dri/intel/intel_depthstencil.h b/src/mesa/drivers/dri/intel/intel_depthstencil.h deleted file mode 100644 index 740eb0d9895..00000000000 --- a/src/mesa/drivers/dri/intel/intel_depthstencil.h +++ /dev/null @@ -1,15 +0,0 @@ - -#ifndef INTEL_DEPTH_STENCIL_H -#define INTEL_DEPTH_STENCIL_H - -#include "intel_fbo.h" - -extern void -intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb); - -extern void -intel_validate_paired_depth_stencil(GLcontext * ctx, - struct gl_framebuffer *fb); - - -#endif /* INTEL_DEPTH_STENCIL_H */ diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c new file mode 100644 index 00000000000..9058e48bc5d --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -0,0 +1,185 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "intel_chipset.h" +#include "intel_context.h" +#include "intel_extensions.h" + + +#define need_GL_ARB_framebuffer_object +#define need_GL_ARB_occlusion_query +#define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects +#define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_framebuffer_blit +#define need_GL_EXT_point_parameters +#define need_GL_EXT_secondary_color +#define need_GL_EXT_stencil_two_side +#define need_GL_ATI_separate_stencil +#define need_GL_NV_point_sprite +#define need_GL_NV_vertex_program +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 + +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * Extensions supported by all chips supported by i830_dri, i915_dri, or + * i965_dri. + */ +static const struct dri_extension card_extensions[] = { + { "GL_ARB_multitexture", NULL }, + { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, + { "GL_ARB_texture_border_clamp", NULL }, + { "GL_ARB_texture_cube_map", NULL }, + { "GL_ARB_texture_env_add", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_mirrored_repeat", NULL }, + { "GL_ARB_texture_rectangle", NULL }, + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, + { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, + { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, + { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, + { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, + { "GL_EXT_blend_logic_op", NULL }, + { "GL_EXT_blend_subtract", NULL }, + { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_packed_depth_stencil", NULL }, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_EXT_texture_edge_clamp", NULL }, + { "GL_EXT_texture_env_combine", NULL }, + { "GL_EXT_texture_env_dot3", NULL }, + { "GL_EXT_texture_filter_anisotropic", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_3DFX_texture_compression_FXT1", NULL }, + { "GL_APPLE_client_storage", NULL }, + { "GL_MESA_pack_invert", NULL }, + { "GL_MESA_ycbcr_texture", NULL }, + { "GL_NV_blend_square", NULL }, + { "GL_NV_point_sprite", GL_NV_point_sprite_functions }, + { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, + { "GL_NV_vertex_program1_1", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, + { NULL, NULL } +}; + + +/** i915 / i945-only extensions */ +static const struct dri_extension i915_extensions[] = { + { "GL_ARB_depth_texture", NULL }, + { "GL_ARB_fragment_program", NULL }, + { "GL_ARB_shadow", NULL }, + { "GL_ARB_texture_non_power_of_two", NULL }, + { "GL_ATI_texture_env_combine3", NULL }, + { "GL_EXT_shadow_funcs", NULL }, + { "GL_NV_texture_env_combine4", NULL }, + { NULL, NULL } +}; + + +/** i965-only extensions */ +static const struct dri_extension brw_extensions[] = { + { "GL_ARB_depth_texture", NULL }, + { "GL_ARB_fragment_program", NULL }, + { "GL_ARB_fragment_program_shadow", NULL }, + { "GL_ARB_fragment_shader", NULL }, + { "GL_ARB_framebuffer_object", GL_ARB_framebuffer_object_functions}, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, + { "GL_ARB_point_sprite", NULL }, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, + { "GL_ARB_shadow", NULL }, + { "GL_ARB_texture_non_power_of_two", NULL }, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, + { "GL_EXT_shadow_funcs", NULL }, + { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, + { "GL_EXT_texture_sRGB", NULL }, + { "GL_EXT_texture_swizzle", NULL }, + { "GL_EXT_vertex_array_bgra", NULL }, + { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions }, + { "GL_ATI_texture_env_combine3", NULL }, + { "GL_NV_texture_env_combine4", NULL }, + { NULL, NULL } +}; + + +static const struct dri_extension arb_oq_extensions[] = { + { NULL, NULL } +}; + + +static const struct dri_extension ttm_extensions[] = { + { "GL_ARB_pixel_buffer_object", NULL }, + { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions }, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { NULL, NULL } +}; + + +/** + * Initializes potential list of extensions if ctx == NULL, or actually enables + * extensions for a context. + */ +void +intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + struct intel_context *intel = ctx?intel_context(ctx):NULL; + + /* Disable imaging extension until convolution is working in teximage paths. + */ + enable_imaging = GL_FALSE; + + driInitExtensions(ctx, card_extensions, enable_imaging); + + if (intel == NULL || intel->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + + if (intel == NULL || IS_965(intel->intelScreen->deviceID)) + driInitExtensions(ctx, brw_extensions, GL_FALSE); + + if (intel == NULL || IS_915(intel->intelScreen->deviceID) + || IS_945(intel->intelScreen->deviceID)) + driInitExtensions(ctx, i915_extensions, GL_FALSE); +} diff --git a/src/mesa/drivers/dri/intel/intel_extensions.h b/src/mesa/drivers/dri/intel/intel_extensions.h new file mode 100644 index 00000000000..97147ecdb0f --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_extensions.h @@ -0,0 +1,36 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#ifndef INTEL_EXTENSIONS_H +#define INTEL_EXTENSIONS_H + + +extern void +intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); + + +#endif diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 7cf12619d6b..54d6044ad3b 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -27,6 +27,7 @@ #include "main/imports.h" +#include "main/macros.h" #include "main/mtypes.h" #include "main/fbobject.h" #include "main/framebuffer.h" @@ -37,58 +38,13 @@ #include "intel_context.h" #include "intel_buffers.h" -#include "intel_depthstencil.h" #include "intel_fbo.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "intel_span.h" #define FILE_DEBUG_FLAG DEBUG_FBO -#define INTEL_RB_CLASS 0x12345678 - - -/* XXX FBO: move this to intel_context.h (inlined) */ -/** - * Return a gl_renderbuffer ptr casted to intel_renderbuffer. - * NULL will be returned if the rb isn't really an intel_renderbuffer. - * This is determiend by checking the ClassID. - */ -struct intel_renderbuffer * -intel_renderbuffer(struct gl_renderbuffer *rb) -{ - struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; - if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { - /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ - return irb; - } - else - return NULL; -} - - -struct intel_renderbuffer * -intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) -{ - if (attIndex >= 0) - return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); - else - return NULL; -} - -struct intel_region * -intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) -{ - struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); - - if (irb) - return irb->region; - else - return NULL; -} - - /** * Create a new framebuffer object. @@ -103,6 +59,7 @@ intel_new_framebuffer(GLcontext * ctx, GLuint name) } +/** Called by gl_renderbuffer::Delete() */ static void intel_delete_renderbuffer(struct gl_renderbuffer *rb) { @@ -112,10 +69,6 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) ASSERT(irb); - if (irb->PairedStencil || irb->PairedDepth) { - intel_unpair_depth_stencil(ctx, irb); - } - if (irb->span_cache != NULL) _mesa_free(irb->span_cache); @@ -127,7 +80,6 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) } - /** * Return a pointer to a specific pixel in a renderbuffer. */ @@ -142,7 +94,6 @@ intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, } - /** * Called via glRenderbufferStorageEXT() to set the format and allocate * storage for a user-created renderbuffer. @@ -211,18 +162,11 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, cpp = 4; break; case GL_DEPTH_COMPONENT16: -#if 0 rb->_ActualFormat = GL_DEPTH_COMPONENT16; rb->DataType = GL_UNSIGNED_SHORT; rb->DepthBits = 16; cpp = 2; break; -#else - /* fall-through. - * 16bpp depth renderbuffer can't be paired with a stencil buffer so - * always used combined depth/stencil format. - */ -#endif case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: @@ -280,7 +224,6 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, } - /** * Called for each hardware renderbuffer when a _window_ is resized. * Just update fields. @@ -298,6 +241,7 @@ intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, return GL_TRUE; } + static void intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, GLuint width, GLuint height) @@ -324,6 +268,8 @@ intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, } } + +/** Dummy function for gl_renderbuffer::AllocStorage() */ static GLboolean intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) @@ -343,10 +289,9 @@ intel_renderbuffer_set_region(struct intel_renderbuffer *rb, rb->region = NULL; intel_region_reference(&rb->region, region); intel_region_release(&old); - - rb->pfPitch = region->pitch; } + /** * Create a new intel_renderbuffer which corresponds to an on-screen window, * not a user-created renderbuffer. @@ -466,9 +411,6 @@ intel_bind_framebuffer(GLcontext * ctx, GLenum target, { if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { intel_draw_buffer(ctx, fb); - /* Integer depth range depends on depth buffer bits */ - if (ctx->Driver.DepthRange != NULL) - ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); } else { /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ @@ -492,6 +434,7 @@ intel_framebuffer_renderbuffer(GLcontext * ctx, intel_draw_buffer(ctx, fb); } + static GLboolean intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, struct gl_texture_image *texImage) @@ -538,11 +481,10 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, irb->Base.Delete = intel_delete_renderbuffer; irb->Base.AllocStorage = intel_nop_alloc_storage; - irb->RenderToTexture = GL_TRUE; - return GL_TRUE; } + /** * When glFramebufferTexture[123]D is called this function sets up the * gl_renderbuffer wrapper around the texture image. @@ -551,7 +493,7 @@ intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, static struct intel_renderbuffer * intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) { - const GLuint name = ~0; /* not significant, but distinct for debugging */ + const GLuint name = ~0; /* not significant, but distinct for debugging */ struct intel_renderbuffer *irb; /* make an intel_renderbuffer to wrap the texture image */ @@ -598,10 +540,11 @@ intel_render_texture(GLcontext * ctx, /* Fallback on drawing to a texture with a border, which won't have a * miptree. */ - _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); - _mesa_render_texture(ctx, fb, att); - return; - } else if (!irb) { + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_render_texture(ctx, fb, att); + return; + } + else if (!irb) { irb = intel_wrap_texture(ctx, newImage); if (irb) { /* bind the wrapper to the attachment point */ @@ -612,7 +555,9 @@ intel_render_texture(GLcontext * ctx, _mesa_render_texture(ctx, fb, att); return; } - } if (!intel_update_wrapper(ctx, irb, newImage)) { + } + + if (!intel_update_wrapper(ctx, irb, newImage)) { _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); _mesa_render_texture(ctx, fb, att); return; @@ -674,6 +619,94 @@ intel_finish_render_texture(GLcontext * ctx, /** + * Do additional "completeness" testing of a framebuffer object. + */ +static void +intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ + const struct intel_renderbuffer *depthRb = + intel_get_renderbuffer(fb, BUFFER_DEPTH); + const struct intel_renderbuffer *stencilRb = + intel_get_renderbuffer(fb, BUFFER_STENCIL); + + if (stencilRb && stencilRb != depthRb) { + /* we only support combined depth/stencil buffers, not separate + * stencil buffers. + */ + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + } +} + + +/** + * Called from glBlitFramebuffer(). + * For now, we're doing an approximation with glCopyPixels(). + * XXX we need to bypass all the per-fragment operations, except scissor. + */ +static void +intel_blit_framebuffer(GLcontext *ctx, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + const GLfloat xZoomSave = ctx->Pixel.ZoomX; + const GLfloat yZoomSave = ctx->Pixel.ZoomY; + GLsizei width, height; + GLfloat xFlip = 1.0F, yFlip = 1.0F; + + if (srcX1 < srcX0) { + GLint tmp = srcX1; + srcX1 = srcX0; + srcX0 = tmp; + xFlip = -1.0F; + } + + if (srcY1 < srcY0) { + GLint tmp = srcY1; + srcY1 = srcY0; + srcY0 = tmp; + yFlip = -1.0F; + } + + width = srcX1 - srcX0; + height = srcY1 - srcY0; + + ctx->Pixel.ZoomX = xFlip * (dstX1 - dstX0) / (srcX1 - srcY0); + ctx->Pixel.ZoomY = yFlip * (dstY1 - dstY0) / (srcY1 - srcY0); + + if (ctx->Pixel.ZoomX < 0.0F) { + dstX0 = MAX2(dstX0, dstX1); + } + else { + dstX0 = MIN2(dstX0, dstX1); + } + + if (ctx->Pixel.ZoomY < 0.0F) { + dstY0 = MAX2(dstY0, dstY1); + } + else { + dstY0 = MIN2(dstY0, dstY1); + } + + if (mask & GL_COLOR_BUFFER_BIT) { + ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height, + dstX0, dstY0, GL_COLOR); + } + if (mask & GL_DEPTH_BUFFER_BIT) { + ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height, + dstX0, dstY0, GL_DEPTH); + } + if (mask & GL_STENCIL_BUFFER_BIT) { + ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height, + dstX0, dstY0, GL_STENCIL); + } + + ctx->Pixel.ZoomX = xZoomSave; + ctx->Pixel.ZoomY = yZoomSave; +} + + +/** * Do one-time context initializations related to GL_EXT_framebuffer_object. * Hook in device driver functions. */ @@ -687,4 +720,6 @@ intel_fbo_init(struct intel_context *intel) intel->ctx.Driver.RenderTexture = intel_render_texture; intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; intel->ctx.Driver.ResizeBuffers = intel_resize_buffers; + intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer; + intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer; } diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h index b7e9280e8cc..7226ee026f6 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.h +++ b/src/mesa/drivers/dri/intel/intel_fbo.h @@ -55,19 +55,11 @@ struct intel_framebuffer /** * Intel renderbuffer, derived from gl_renderbuffer. - * Note: The PairedDepth and PairedStencil fields use renderbuffer IDs, - * not pointers because in some circumstances a deleted renderbuffer could - * result in a dangling pointer here. */ struct intel_renderbuffer { struct gl_renderbuffer Base; struct intel_region *region; - GLuint pfPitch; /* possibly paged flipped pitch */ - GLboolean RenderToTexture; /* RTT? */ - - GLuint PairedDepth; /**< only used if this is a depth renderbuffer */ - GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */ GLuint vbl_pending; /**< vblank sequence number of pending flip */ @@ -75,48 +67,70 @@ struct intel_renderbuffer unsigned long span_cache_offset; }; -extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer - *rb); + +/** + * gl_renderbuffer is a base class which we subclass. The Class field + * is used for simple run-time type checking. + */ +#define INTEL_RB_CLASS 0x12345678 + + +/** + * Return a gl_renderbuffer ptr casted to intel_renderbuffer. + * NULL will be returned if the rb isn't really an intel_renderbuffer. + * This is determined by checking the ClassID. + */ +static INLINE struct intel_renderbuffer * +intel_renderbuffer(struct gl_renderbuffer *rb) +{ + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { + /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ + return irb; + } + else + return NULL; +} + + +/** + * Return a framebuffer's renderbuffer, named by a BUFFER_x index. + */ +static INLINE struct intel_renderbuffer * +intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) +{ + if (attIndex >= 0) + return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); + else + return NULL; +} + extern void intel_renderbuffer_set_region(struct intel_renderbuffer *irb, struct intel_region *region); + extern struct intel_renderbuffer * intel_create_renderbuffer(GLenum intFormat); -extern void intel_fbo_init(struct intel_context *intel); - - -/* XXX make inline or macro */ -extern struct intel_renderbuffer *intel_get_renderbuffer(struct gl_framebuffer - *fb, - int attIndex); - -extern void intel_flip_renderbuffers(struct intel_framebuffer *intel_fb); +extern void +intel_fbo_init(struct intel_context *intel); -/* XXX make inline or macro */ -extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, - GLuint attIndex); +extern void +intel_flip_renderbuffers(struct intel_framebuffer *intel_fb); -/** - * Are we currently rendering into a texture? - */ -static INLINE GLboolean -intel_rendering_to_texture(const GLcontext *ctx) +static INLINE struct intel_region * +intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) { - if (ctx->DrawBuffer->Name) { - /* User-created FBO */ - const struct intel_renderbuffer *irb = - intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); - return irb && irb->RenderToTexture; - } - else { - return GL_FALSE; - } + struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); + if (irb) + return irb->region; + else + return NULL; } diff --git a/src/mesa/drivers/dri/intel/intel_pixel.h b/src/mesa/drivers/dri/intel/intel_pixel.h index 76b8781316b..cb41fa182cb 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.h +++ b/src/mesa/drivers/dri/intel/intel_pixel.h @@ -76,4 +76,6 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); +void intel_clear_tris(GLcontext *ctx, GLbitfield mask); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 3a01f63dc72..1db7f5594e9 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -495,6 +495,7 @@ intel_texture_bitmap(GLcontext * ctx, 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); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index bb36649dacd..7be7ea82b35 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -72,6 +72,8 @@ intel_texture_drawpixels(GLcontext * ctx, GLfloat vertices[4][4]; GLfloat texcoords[4][2]; GLfloat z; + GLint old_active_texture; + GLenum internalFormat; /* We're going to mess with texturing with no regard to existing texture * state, so if there is some set up we have to bail. @@ -125,6 +127,7 @@ intel_texture_drawpixels(GLcontext * ctx, /* XXX: pixel store stuff */ _mesa_Disable(GL_POLYGON_STIPPLE); + old_active_texture = ctx->Texture.CurrentUnit; _mesa_ActiveTextureARB(GL_TEXTURE0_ARB); _mesa_Enable(GL_TEXTURE_2D); _mesa_GenTextures(1, &texname); @@ -132,11 +135,11 @@ intel_texture_drawpixels(GLcontext * ctx, _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); _mesa_TexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - /* - _mesa_TexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - _mesa_TexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - */ - _mesa_TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, + if (type == GL_ALPHA) + internalFormat = GL_ALPHA; + else + internalFormat = GL_RGBA; + _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, pixels); intel_meta_set_passthrough_transform(intel); @@ -176,12 +179,15 @@ intel_texture_drawpixels(GLcontext * ctx, 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); CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4)); intel_meta_restore_transform(intel); + + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_PopClientAttrib(); _mesa_PopAttrib(); @@ -209,6 +215,7 @@ intel_stencil_drawpixels(GLcontext * ctx, struct gl_pixelstore_attrib old_unpack; GLstencil *stencil_pixels; int row; + GLint old_active_texture; if (format != GL_STENCIL_INDEX) return GL_FALSE; @@ -270,6 +277,7 @@ intel_stencil_drawpixels(GLcontext * ctx, GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); old_fb_name = ctx->DrawBuffer->Name; + old_active_texture = ctx->Texture.CurrentUnit; _mesa_Disable(GL_POLYGON_STIPPLE); _mesa_Disable(GL_DEPTH_TEST); @@ -355,6 +363,7 @@ intel_stencil_drawpixels(GLcontext * ctx, 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); @@ -362,6 +371,7 @@ intel_stencil_drawpixels(GLcontext * ctx, intel_meta_restore_transform(intel); + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, old_fb_name); _mesa_PopClientAttrib(); diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 51ce32a9679..ec85c4131a1 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -152,7 +152,7 @@ void intel_region_reference(struct intel_region **dst, struct intel_region *src) { if (src) - DBG("%s %d\n", __FUNCTION__, src->refcount); + DBG("%s %p %d\n", __FUNCTION__, src, src->refcount); assert(*dst == NULL); if (src) { @@ -169,7 +169,7 @@ intel_region_release(struct intel_region **region_handle) if (region == NULL) return; - DBG("%s %d\n", __FUNCTION__, region->refcount - 1); + DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1); ASSERT(region->refcount > 0); region->refcount--; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 7042c255644..a52271158c6 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -28,27 +28,27 @@ #include "main/glheader.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/matrix.h" #include "main/renderbuffer.h" -#include "main/simple_list.h" + #include "utils.h" #include "vblank.h" #include "xmlpool.h" - -#include "intel_screen.h" - +#include "intel_batchbuffer.h" #include "intel_buffers.h" -#include "intel_tex.h" -#include "intel_span.h" -#include "intel_fbo.h" +#include "intel_bufmgr.h" #include "intel_chipset.h" +#include "intel_extensions.h" +#include "intel_fbo.h" +#include "intel_regions.h" +#include "intel_swapbuffers.h" +#include "intel_screen.h" +#include "intel_span.h" +#include "intel_tex.h" #include "i915_drm.h" #include "i830_dri.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" -#include "intel_bufmgr.h" + PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -159,7 +159,7 @@ intelPrintSAREA(const drm_i915_sarea_t * sarea) * A number of the screen parameters are obtained/computed from * information in the SAREA. This function updates those parameters. */ -void +static void intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, drm_i915_sarea_t * sarea) { @@ -316,8 +316,6 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, __DRIdrawablePrivate * driDrawPriv, const __GLcontextModes * mesaVis, GLboolean isPixmap) { - intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; - if (isPixmap) { return GL_FALSE; /* not implemented */ } @@ -467,8 +465,6 @@ intelFillInModes(__DRIscreenPrivate *psp, __GLcontextModes *m; unsigned depth_buffer_factor; unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't @@ -480,6 +476,7 @@ intelFillInModes(__DRIscreenPrivate *psp, uint8_t depth_bits_array[3]; uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; @@ -496,22 +493,39 @@ intelFillInModes(__DRIscreenPrivate *psp, stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + msaa_samples_array[0] = 0; + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; back_buffer_factor = (have_back_buffer) ? 3 : 1; if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; + configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, + msaa_samples_array, 1); } else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + __DRIconfig **configs_a8r8g8b8; + __DRIconfig **configs_x8r8g8b8; + + configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + msaa_samples_array, 1); + configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + msaa_samples_array, 1); + configs = driConcatConfigs(configs_a8r8g8b8, configs_x8r8g8b8); } - configs = driCreateConfigs(fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); @@ -673,6 +687,17 @@ static const __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) { intelScreenPrivate *intelScreen; + GLenum fb_format[3]; + GLenum fb_type[3]; + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; + int color; + __DRIconfig **configs = NULL; /* Calling driInitExtensions here, with a NULL context pointer, * does not actually enable the extensions. It just makes sure @@ -712,8 +737,50 @@ __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) intelScreen->irq_active = 1; psp->extensions = intelScreenExtensions; - return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), - intelFillInModes(psp, 32, 24, 8, 1)); + depth_bits[0] = 0; + stencil_bits[0] = 0; + depth_bits[1] = 16; + stencil_bits[1] = 0; + depth_bits[2] = 24; + stencil_bits[2] = 0; + depth_bits[3] = 24; + stencil_bits[3] = 8; + + msaa_samples_array[0] = 0; + + fb_format[0] = GL_RGB; + fb_type[0] = GL_UNSIGNED_SHORT_5_6_5; + + fb_format[1] = GL_BGR; + fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV; + + fb_format[2] = GL_BGRA; + fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV; + + for (color = 0; color < ARRAY_SIZE(fb_format); color++) { + __DRIconfig **new_configs; + + new_configs = driCreateConfigs(fb_format[color], fb_type[color], + depth_bits, + stencil_bits, + ARRAY_SIZE(depth_bits), + back_buffer_modes, + ARRAY_SIZE(back_buffer_modes), + msaa_samples_array, + ARRAY_SIZE(msaa_samples_array)); + if (configs == NULL) + configs = new_configs; + else + configs = driConcatConfigs(configs, new_configs); + } + + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + return (const __DRIconfig **)configs; } const struct __DriverAPIRec driDriverAPI = { diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index fcd0d9c28c7..e1036de4db8 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -92,10 +92,6 @@ extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); -extern void -intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, - drm_i915_sarea_t * sarea); - extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); @@ -105,11 +101,6 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driDrawPriv, __DRIdrawablePrivate * driReadPriv); -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); - extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); #endif diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index d9315043e6e..bdd2fd9e857 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -150,7 +150,7 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb, int x_tile_number, y_tile_number; int tile_off, tile_base; - tile_stride = (irb->pfPitch * irb->region->cpp) << 3; + tile_stride = (irb->region->pitch * irb->region->cpp) << 3; xbyte = x * irb->region->cpp; @@ -190,7 +190,7 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb, printf("(%d,%d) -> %d + %d = %d (pitch = %d, tstride = %d)\n", x, y, tile_off, tile_base, tile_off + tile_base, - irb->pfPitch, tile_stride); + irb->region->pitch, tile_stride); #endif return tile_base + tile_off; @@ -205,7 +205,7 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, int x_tile_number, y_tile_number; int tile_off, tile_base; - tile_stride = (irb->pfPitch * irb->region->cpp) << 5; + tile_stride = (irb->region->pitch * irb->region->cpp) << 5; xbyte = x * irb->region->cpp; @@ -255,8 +255,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define LOCAL_VARS \ struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ - const GLint yScale = irb->RenderToTexture ? 1 : -1; \ - const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ + const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ unsigned int num_cliprects; \ struct drm_clip_rect *cliprects; \ int x_off, y_off; \ @@ -392,8 +392,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define LOCAL_DEPTH_VARS \ struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ - const GLint yScale = irb->RenderToTexture ? 1 : -1; \ - const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ + const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ unsigned int num_cliprects; \ struct drm_clip_rect *cliprects; \ int x_off, y_off; \ @@ -528,8 +528,6 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb) if (irb == NULL || irb->region == NULL) return; - irb->pfPitch = irb->region->pitch; - intel_set_span_functions(intel, rb); } @@ -543,7 +541,6 @@ intel_renderbuffer_unmap(struct intel_context *intel, return; clear_span_cache(irb); - irb->pfPitch = 0; rb->GetRow = NULL; rb->PutRow = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_state.c b/src/mesa/drivers/dri/intel/intel_state.c new file mode 100644 index 00000000000..4ee742377d6 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_state.c @@ -0,0 +1,233 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + + +#include "main/glheader.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/enums.h" +#include "main/colormac.h" +#include "main/dd.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_regions.h" +#include "swrast/swrast.h" + +int +intel_translate_shadow_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_ALWAYS; + case GL_LESS: + return COMPAREFUNC_LEQUAL; + case GL_LEQUAL: + return COMPAREFUNC_LESS; + case GL_GREATER: + return COMPAREFUNC_GEQUAL; + case GL_GEQUAL: + return COMPAREFUNC_GREATER; + case GL_NOTEQUAL: + return COMPAREFUNC_EQUAL; + case GL_EQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_ALWAYS: + return COMPAREFUNC_NEVER; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_NEVER; +} + +int +intel_translate_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_NEVER; + case GL_LESS: + return COMPAREFUNC_LESS; + case GL_LEQUAL: + return COMPAREFUNC_LEQUAL; + case GL_GREATER: + return COMPAREFUNC_GREATER; + case GL_GEQUAL: + return COMPAREFUNC_GEQUAL; + case GL_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_EQUAL: + return COMPAREFUNC_EQUAL; + case GL_ALWAYS: + return COMPAREFUNC_ALWAYS; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_ALWAYS; +} + +int +intel_translate_stencil_op(GLenum op) +{ + switch (op) { + case GL_KEEP: + return STENCILOP_KEEP; + case GL_ZERO: + return STENCILOP_ZERO; + case GL_REPLACE: + return STENCILOP_REPLACE; + case GL_INCR: + return STENCILOP_INCRSAT; + case GL_DECR: + return STENCILOP_DECRSAT; + case GL_INCR_WRAP: + return STENCILOP_INCR; + case GL_DECR_WRAP: + return STENCILOP_DECR; + case GL_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +int +intel_translate_blend_factor(GLenum factor) +{ + switch (factor) { + case GL_ZERO: + return BLENDFACT_ZERO; + case GL_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case GL_ONE: + return BLENDFACT_ONE; + case GL_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case GL_ONE_MINUS_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case GL_DST_COLOR: + return BLENDFACT_DST_COLR; + case GL_ONE_MINUS_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case GL_ONE_MINUS_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case GL_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case GL_CONSTANT_COLOR: + return BLENDFACT_CONST_COLOR; + case GL_ONE_MINUS_CONSTANT_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case GL_CONSTANT_ALPHA: + return BLENDFACT_CONST_ALPHA; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); + return BLENDFACT_ZERO; +} + +int +intel_translate_logic_op(GLenum opcode) +{ + switch (opcode) { + case GL_CLEAR: + return LOGICOP_CLEAR; + case GL_AND: + return LOGICOP_AND; + case GL_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case GL_COPY: + return LOGICOP_COPY; + case GL_COPY_INVERTED: + return LOGICOP_COPY_INV; + case GL_AND_INVERTED: + return LOGICOP_AND_INV; + case GL_NOOP: + return LOGICOP_NOOP; + case GL_XOR: + return LOGICOP_XOR; + case GL_OR: + return LOGICOP_OR; + case GL_OR_INVERTED: + return LOGICOP_OR_INV; + case GL_NOR: + return LOGICOP_NOR; + case GL_EQUIV: + return LOGICOP_EQUIV; + case GL_INVERT: + return LOGICOP_INV; + case GL_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case GL_NAND: + return LOGICOP_NAND; + case GL_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + + +static void +intelClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + struct intel_context *intel = intel_context(ctx); + GLubyte clear[4]; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + /* compute both 32 and 16-bit clear values */ + intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], + clear[2], clear[3]); + intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); +} + + +/* Fallback to swrast for select and feedback. + */ +static void +intelRenderMode(GLcontext *ctx, GLenum mode) +{ + struct intel_context *intel = intel_context(ctx); + FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); +} + + +void +intelInitStateFuncs(struct dd_function_table *functions) +{ + functions->RenderMode = intelRenderMode; + functions->ClearColor = intelClearColor; +} diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.c b/src/mesa/drivers/dri/intel/intel_swapbuffers.c new file mode 100644 index 00000000000..7d035b9f6e4 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_swapbuffers.c @@ -0,0 +1,248 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_swapbuffers.h" +#include "intel_fbo.h" +#include "intel_batchbuffer.h" +#include "drirenderbuffer.h" +#include "vblank.h" +#include "i915_drm.h" + + + +/* + * Correct a drawablePrivate's set of vblank flags WRT the current context. + * When considering multiple crtcs. + */ +GLuint +intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv) +{ + if (!intel->intelScreen->driScrnPriv->dri2.enabled && + intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { + volatile drm_i915_sarea_t *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); + GLuint flags = dPriv->vblFlags; + + /* Update vblank info + */ + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; + } else { + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } + + /* Do the stupid test: Is one of them actually disabled? + */ + if (sarea->planeA_w == 0 || sarea->planeA_h == 0) { + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; + } else if (sarea->planeB_w == 0 || sarea->planeB_h == 0) { + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } + + return flags; + } else { + return dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } +} + + +/** + * Called from driSwapBuffers() + */ +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + __DRIscreenPrivate *psp = dPriv->driScreenPriv; + + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel; + + if (ctx == NULL) + return; + + intel = intel_context(ctx); + + if (ctx->Visual.doubleBufferMode) { + GLboolean missed_target; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + int64_t ust; + + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + + /* + * The old swapping ioctl was incredibly racy, just wait for vblank + * and do the swap ourselves. + */ + driWaitForVBlank(dPriv, &missed_target); + + /* + * Update each buffer's vbl_pending so we don't get too out of + * sync + */ + intel_get_renderbuffer(&intel_fb->Base, + BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq; + intel_get_renderbuffer(&intel_fb->Base, + BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; + + intelCopyBuffer(dPriv, NULL); + + intel_fb->swap_count++; + (*psp->systemTime->getUST) (&ust); + if (missed_target) { + intel_fb->swap_missed_count++; + intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; + } + + intel_fb->swap_ust = ust; + } + drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE); + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + + +/** + * Called from driCopySubBuffer() + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + struct intel_context *intel = + (struct intel_context *) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + if (ctx->Visual.doubleBufferMode) { + drm_clip_rect_t rect; + rect.x1 = x + dPriv->x; + rect.y1 = (dPriv->h - y - h) + dPriv->y; + rect.x2 = rect.x1 + w; + rect.y2 = rect.y1 + h; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + intelCopyBuffer(dPriv, &rect); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + + +/** + * This will be called whenever the currently bound window is moved/resized. + * XXX: actually, it seems to NOT be called when the window is only moved (BP). + */ +void +intelWindowMoved(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + + if (!intel->intelScreen->driScrnPriv->dri2.enabled && + intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { + GLuint flags = intelFixupVblank(intel, dPriv); + + /* Check to see if we changed pipes */ + if (flags != dPriv->vblFlags && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + int64_t count; + drmVBlank vbl; + int i; + + /* + * Deal with page flipping + */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + + for (i = 0; i < 2; i++) { + if (!intel_fb->color_rb[i] || + (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= + (1<<23)) + continue; + + vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; + drmWaitVBlank(intel->driFd, &vbl); + } + + /* + * Update msc_base from old pipe + */ + driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); + dPriv->msc_base = count; + /* + * Then get new vblank_base and vblSeq values + */ + dPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv); + dPriv->vblank_base = dPriv->vblSeq; + + intel_fb->vbl_waited = dPriv->vblSeq; + + for (i = 0; i < 2; i++) { + if (intel_fb->color_rb[i]) + intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; + } + } + } else { + dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; + } + + /* Update Mesa's notion of window size */ + driUpdateFramebufferSize(ctx, dPriv); + intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ + + /* Update hardware scissor */ + if (ctx->Driver.Scissor != NULL) { + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + } + + /* Re-calculate viewport related state */ + if (ctx->Driver.DepthRange != NULL) + ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); +} diff --git a/src/mesa/drivers/dri/intel/intel_swapbuffers.h b/src/mesa/drivers/dri/intel/intel_swapbuffers.h new file mode 100644 index 00000000000..75bb6242ffc --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_swapbuffers.h @@ -0,0 +1,52 @@ + +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN GRAPHICS 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. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + +#include "dri_util.h" +#include "drm.h" + +struct intel_context; +struct intel_framebuffer; + + +extern void +intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); + +extern GLuint +intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv); + +extern void +intelWindowMoved(struct intel_context *intel); + + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c index e64d8a1556d..ae0994b183a 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.c +++ b/src/mesa/drivers/dri/intel/intel_tex.c @@ -93,7 +93,7 @@ intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) static void * do_memcpy(void *dest, const void *src, size_t n) { - if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { + if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) { return __memcpy(dest, src, n); } else diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c index 5e418ac4463..2715a540d02 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_format.c +++ b/src/mesa/drivers/dri/intel/intel_tex_format.c @@ -16,7 +16,7 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, GLenum format, GLenum type) { struct intel_context *intel = intel_context(ctx); - const GLboolean do32bpt = (intel->ctx.Visual.rgbBits == 32); + const GLboolean do32bpt = (intel->ctx.Visual.rgbBits >= 24); switch (internalFormat) { case 4: diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 2ac7dceb0fc..866022d0ce2 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -209,7 +209,8 @@ try_pbo_upload(struct intel_context *intel, return GL_FALSE; } - src_offset = (GLuint) pixels; + /* note: potential 64-bit ptr to 32-bit int cast */ + src_offset = (GLuint) (unsigned long) pixels; if (unpack->RowLength > 0) src_stride = unpack->RowLength; @@ -264,7 +265,8 @@ try_pbo_zcopy(struct intel_context *intel, return GL_FALSE; } - src_offset = (GLuint) pixels; + /* note: potential 64-bit ptr to 32-bit int cast */ + src_offset = (GLuint) (unsigned long) pixels; if (unpack->RowLength > 0) src_stride = unpack->RowLength; |