1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "intel_screen.h"
29 #include "intel_context.h"
30 #include "intel_blit.h"
31 #include "intel_buffers.h"
32 #include "intel_chipset.h"
33 #include "intel_depthstencil.h"
34 #include "intel_fbo.h"
35 #include "intel_regions.h"
36 #include "intel_batchbuffer.h"
37 #include "intel_reg.h"
38 #include "main/context.h"
39 #include "main/framebuffer.h"
40 #include "swrast/swrast.h"
42 #include "drirenderbuffer.h"
46 #define FILE_DEBUG_FLAG DEBUG_BLIT
49 * XXX move this into a new dri/common/cliprects.c file.
52 intel_intersect_cliprects(drm_clip_rect_t
* dst
,
53 const drm_clip_rect_t
* a
,
54 const drm_clip_rect_t
* b
)
58 GLint bw
= b
->x2
- bx
;
59 GLint bh
= b
->y2
- by
;
62 bw
-= a
->x1
- bx
, bx
= a
->x1
;
64 bh
-= a
->y1
- by
, by
= a
->y1
;
83 * Return pointer to current color drawing region, or NULL.
86 intel_drawbuf_region(struct intel_context
*intel
)
88 struct intel_renderbuffer
*irbColor
=
89 intel_renderbuffer(intel
->ctx
.DrawBuffer
->_ColorDrawBuffers
[0]);
91 return irbColor
->region
;
97 * Return pointer to current color reading region, or NULL.
100 intel_readbuf_region(struct intel_context
*intel
)
102 struct intel_renderbuffer
*irb
103 = intel_renderbuffer(intel
->ctx
.ReadBuffer
->_ColorReadBuffer
);
111 intel_get_cliprects(struct intel_context
*intel
,
112 struct drm_clip_rect
**cliprects
,
113 unsigned int *num_cliprects
,
114 int *x_off
, int *y_off
)
116 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
117 struct intel_framebuffer
*intel_fb
= dPriv
->driverPrivate
;
119 if (intel
->constant_cliprect
) {
120 /* FBO or DRI2 rendering, which can just use the fb's size. */
121 intel
->fboRect
.x1
= 0;
122 intel
->fboRect
.y1
= 0;
123 intel
->fboRect
.x2
= intel
->ctx
.DrawBuffer
->Width
;
124 intel
->fboRect
.y2
= intel
->ctx
.DrawBuffer
->Height
;
126 *cliprects
= &intel
->fboRect
;
130 } else if (intel
->front_cliprects
|| dPriv
->numBackClipRects
== 0) {
131 /* use the front clip rects */
132 *cliprects
= dPriv
->pClipRects
;
133 *num_cliprects
= dPriv
->numClipRects
;
138 /* use the back clip rects */
139 *num_cliprects
= dPriv
->numBackClipRects
;
140 *cliprects
= dPriv
->pBackClipRects
;
141 *x_off
= dPriv
->backX
;
142 *y_off
= dPriv
->backY
;
147 * This will be called whenever the currently bound window is moved/resized.
148 * XXX: actually, it seems to NOT be called when the window is only moved (BP).
151 intelWindowMoved(struct intel_context
*intel
)
153 GLcontext
*ctx
= &intel
->ctx
;
154 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
155 struct intel_framebuffer
*intel_fb
= dPriv
->driverPrivate
;
157 if (!intel
->intelScreen
->driScrnPriv
->dri2
.enabled
&&
158 intel
->intelScreen
->driScrnPriv
->ddx_version
.minor
>= 7) {
159 volatile drm_i915_sarea_t
*sarea
= intel
->sarea
;
160 drm_clip_rect_t drw_rect
= { .x1
= dPriv
->x
, .x2
= dPriv
->x
+ dPriv
->w
,
161 .y1
= dPriv
->y
, .y2
= dPriv
->y
+ dPriv
->h
};
162 drm_clip_rect_t planeA_rect
= { .x1
= sarea
->planeA_x
, .y1
= sarea
->planeA_y
,
163 .x2
= sarea
->planeA_x
+ sarea
->planeA_w
,
164 .y2
= sarea
->planeA_y
+ sarea
->planeA_h
};
165 drm_clip_rect_t planeB_rect
= { .x1
= sarea
->planeB_x
, .y1
= sarea
->planeB_y
,
166 .x2
= sarea
->planeB_x
+ sarea
->planeB_w
,
167 .y2
= sarea
->planeB_y
+ sarea
->planeB_h
};
168 GLint areaA
= driIntersectArea( drw_rect
, planeA_rect
);
169 GLint areaB
= driIntersectArea( drw_rect
, planeB_rect
);
170 GLuint flags
= dPriv
->vblFlags
;
172 /* Update vblank info
174 if (areaB
> areaA
|| (areaA
== areaB
&& areaB
> 0)) {
175 flags
= dPriv
->vblFlags
| VBLANK_FLAG_SECONDARY
;
177 flags
= dPriv
->vblFlags
& ~VBLANK_FLAG_SECONDARY
;
180 /* Check to see if we changed pipes */
181 if (flags
!= dPriv
->vblFlags
&& dPriv
->vblFlags
&&
182 !(dPriv
->vblFlags
& VBLANK_FLAG_NO_IRQ
)) {
188 * Deal with page flipping
190 vbl
.request
.type
= DRM_VBLANK_ABSOLUTE
;
192 if ( dPriv
->vblFlags
& VBLANK_FLAG_SECONDARY
) {
193 vbl
.request
.type
|= DRM_VBLANK_SECONDARY
;
196 for (i
= 0; i
< 2; i
++) {
197 if (!intel_fb
->color_rb
[i
] ||
198 (intel_fb
->vbl_waited
- intel_fb
->color_rb
[i
]->vbl_pending
) <=
202 vbl
.request
.sequence
= intel_fb
->color_rb
[i
]->vbl_pending
;
203 drmWaitVBlank(intel
->driFd
, &vbl
);
207 * Update msc_base from old pipe
209 driDrawableGetMSC32(dPriv
->driScreenPriv
, dPriv
, &count
);
210 dPriv
->msc_base
= count
;
212 * Then get new vblank_base and vblSeq values
214 dPriv
->vblFlags
= flags
;
215 driGetCurrentVBlank(dPriv
);
216 dPriv
->vblank_base
= dPriv
->vblSeq
;
218 intel_fb
->vbl_waited
= dPriv
->vblSeq
;
220 for (i
= 0; i
< 2; i
++) {
221 if (intel_fb
->color_rb
[i
])
222 intel_fb
->color_rb
[i
]->vbl_pending
= intel_fb
->vbl_waited
;
226 dPriv
->vblFlags
&= ~VBLANK_FLAG_SECONDARY
;
229 /* Update Mesa's notion of window size */
230 driUpdateFramebufferSize(ctx
, dPriv
);
231 intel_fb
->Base
.Initialized
= GL_TRUE
; /* XXX remove someday */
233 /* Update hardware scissor */
234 if (ctx
->Driver
.Scissor
!= NULL
) {
235 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
236 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
239 /* Re-calculate viewport related state */
240 if (ctx
->Driver
.DepthRange
!= NULL
)
241 ctx
->Driver
.DepthRange( ctx
, ctx
->Viewport
.Near
, ctx
->Viewport
.Far
);
246 /* A true meta version of this would be very simple and additionally
247 * machine independent. Maybe we'll get there one day.
250 intelClearWithTris(struct intel_context
*intel
, GLbitfield mask
)
252 GLcontext
*ctx
= &intel
->ctx
;
253 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
256 intel
->vtbl
.install_meta_state(intel
);
258 /* Back and stencil cliprects are the same. Try and do both
261 if (mask
& (BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_STENCIL
| BUFFER_BIT_DEPTH
)) {
262 struct intel_region
*backRegion
=
263 intel_get_rb_region(fb
, BUFFER_BACK_LEFT
);
264 struct intel_region
*depthRegion
=
265 intel_get_rb_region(fb
, BUFFER_DEPTH
);
267 intel
->vtbl
.meta_draw_region(intel
, backRegion
, depthRegion
);
269 if (mask
& BUFFER_BIT_BACK_LEFT
)
270 intel
->vtbl
.meta_color_mask(intel
, GL_TRUE
);
272 intel
->vtbl
.meta_color_mask(intel
, GL_FALSE
);
274 if (mask
& BUFFER_BIT_STENCIL
)
275 intel
->vtbl
.meta_stencil_replace(intel
,
276 intel
->ctx
.Stencil
.WriteMask
[0],
277 intel
->ctx
.Stencil
.Clear
);
279 intel
->vtbl
.meta_no_stencil_write(intel
);
281 if (mask
& BUFFER_BIT_DEPTH
)
282 intel
->vtbl
.meta_depth_replace(intel
);
284 intel
->vtbl
.meta_no_depth_write(intel
);
286 intel
->vtbl
.meta_draw_quad(intel
,
291 intel
->ctx
.Depth
.Clear
,
292 intel
->ClearColor8888
,
293 0, 0, 0, 0); /* texcoords */
295 mask
&= ~(BUFFER_BIT_BACK_LEFT
| BUFFER_BIT_STENCIL
| BUFFER_BIT_DEPTH
);
298 /* clear the remaining (color) renderbuffers */
299 for (buf
= 0; buf
< BUFFER_COUNT
&& mask
; buf
++) {
300 const GLuint bufBit
= 1 << buf
;
302 struct intel_renderbuffer
*irbColor
=
303 intel_renderbuffer(fb
->Attachment
[buf
].Renderbuffer
);
307 intel
->vtbl
.meta_no_depth_write(intel
);
308 intel
->vtbl
.meta_no_stencil_write(intel
);
309 intel
->vtbl
.meta_color_mask(intel
, GL_TRUE
);
310 intel
->vtbl
.meta_draw_region(intel
, irbColor
->region
, NULL
);
312 intel
->vtbl
.meta_draw_quad(intel
,
317 0, intel
->ClearColor8888
,
318 0, 0, 0, 0); /* texcoords */
324 intel
->vtbl
.leave_meta_state(intel
);
327 static const char *buffer_names
[] = {
328 [BUFFER_FRONT_LEFT
] = "front",
329 [BUFFER_BACK_LEFT
] = "back",
330 [BUFFER_FRONT_RIGHT
] = "front right",
331 [BUFFER_BACK_RIGHT
] = "back right",
332 [BUFFER_AUX0
] = "aux0",
333 [BUFFER_AUX1
] = "aux1",
334 [BUFFER_AUX2
] = "aux2",
335 [BUFFER_AUX3
] = "aux3",
336 [BUFFER_DEPTH
] = "depth",
337 [BUFFER_STENCIL
] = "stencil",
338 [BUFFER_ACCUM
] = "accum",
339 [BUFFER_COLOR0
] = "color0",
340 [BUFFER_COLOR1
] = "color1",
341 [BUFFER_COLOR2
] = "color2",
342 [BUFFER_COLOR3
] = "color3",
343 [BUFFER_COLOR4
] = "color4",
344 [BUFFER_COLOR5
] = "color5",
345 [BUFFER_COLOR6
] = "color6",
346 [BUFFER_COLOR7
] = "color7",
350 * Called by ctx->Driver.Clear.
353 intelClear(GLcontext
*ctx
, GLbitfield mask
)
355 struct intel_context
*intel
= intel_context(ctx
);
356 const GLuint colorMask
= *((GLuint
*) & ctx
->Color
.ColorMask
);
357 GLbitfield tri_mask
= 0;
358 GLbitfield blit_mask
= 0;
359 GLbitfield swrast_mask
= 0;
360 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
364 fprintf(stderr
, "%s\n", __FUNCTION__
);
366 /* HW color buffers (front, back, aux, generic FBO, etc) */
367 if (colorMask
== ~0) {
368 /* clear all R,G,B,A */
369 /* XXX FBO: need to check if colorbuffers are software RBOs! */
370 blit_mask
|= (mask
& BUFFER_BITS_COLOR
);
373 /* glColorMask in effect */
374 tri_mask
|= (mask
& BUFFER_BITS_COLOR
);
378 if (mask
& BUFFER_BIT_STENCIL
) {
379 const struct intel_region
*stencilRegion
380 = intel_get_rb_region(fb
, BUFFER_STENCIL
);
382 /* have hw stencil */
383 if (IS_965(intel
->intelScreen
->deviceID
) ||
384 (ctx
->Stencil
.WriteMask
[0] & 0xff) != 0xff) {
385 /* We have to use the 3D engine if we're clearing a partial mask
386 * of the stencil buffer, or if we're on a 965 which has a tiled
387 * depth/stencil buffer in a layout we can't blit to.
389 tri_mask
|= BUFFER_BIT_STENCIL
;
392 /* clearing all stencil bits, use blitting */
393 blit_mask
|= BUFFER_BIT_STENCIL
;
399 if (mask
& BUFFER_BIT_DEPTH
) {
400 /* clear depth with whatever method is used for stencil (see above) */
401 if (IS_965(intel
->intelScreen
->deviceID
) ||
402 tri_mask
& BUFFER_BIT_STENCIL
)
403 tri_mask
|= BUFFER_BIT_DEPTH
;
405 blit_mask
|= BUFFER_BIT_DEPTH
;
408 /* SW fallback clearing */
409 swrast_mask
= mask
& ~tri_mask
& ~blit_mask
;
411 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
412 GLuint bufBit
= 1 << i
;
413 if ((blit_mask
| tri_mask
) & bufBit
) {
414 if (!fb
->Attachment
[i
].Renderbuffer
->ClassID
) {
415 blit_mask
&= ~bufBit
;
417 swrast_mask
|= bufBit
;
423 if (INTEL_DEBUG
& DEBUG_BLIT
) {
425 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
426 if (blit_mask
& (1 << i
))
427 DBG(" %s", buffer_names
[i
]);
431 intelClearWithBlit(ctx
, blit_mask
);
435 if (INTEL_DEBUG
& DEBUG_BLIT
) {
437 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
438 if (tri_mask
& (1 << i
))
439 DBG(" %s", buffer_names
[i
]);
443 intelClearWithTris(intel
, tri_mask
);
447 if (INTEL_DEBUG
& DEBUG_BLIT
) {
448 DBG("swrast clear:");
449 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
450 if (swrast_mask
& (1 << i
))
451 DBG(" %s", buffer_names
[i
]);
455 _swrast_Clear(ctx
, swrast_mask
);
460 intelSwapBuffers(__DRIdrawablePrivate
* dPriv
)
462 __DRIscreenPrivate
*psp
= dPriv
->driScreenPriv
;
464 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
465 GET_CURRENT_CONTEXT(ctx
);
466 struct intel_context
*intel
;
471 intel
= intel_context(ctx
);
473 if (ctx
->Visual
.doubleBufferMode
) {
474 GLboolean missed_target
;
475 struct intel_framebuffer
*intel_fb
= dPriv
->driverPrivate
;
478 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
481 * The old swapping ioctl was incredibly racy, just wait for vblank
482 * and do the swap ourselves.
484 driWaitForVBlank(dPriv
, &missed_target
);
487 * Update each buffer's vbl_pending so we don't get too out of
490 intel_get_renderbuffer(&intel_fb
->Base
,
491 BUFFER_BACK_LEFT
)->vbl_pending
= dPriv
->vblSeq
;
492 intel_get_renderbuffer(&intel_fb
->Base
,
493 BUFFER_FRONT_LEFT
)->vbl_pending
= dPriv
->vblSeq
;
495 intelCopyBuffer(dPriv
, NULL
);
497 intel_fb
->swap_count
++;
498 (*psp
->systemTime
->getUST
) (&ust
);
500 intel_fb
->swap_missed_count
++;
501 intel_fb
->swap_missed_ust
= ust
- intel_fb
->swap_ust
;
504 intel_fb
->swap_ust
= ust
;
506 drmCommandNone(intel
->driFd
, DRM_I915_GEM_THROTTLE
);
510 /* XXX this shouldn't be an error but we can't handle it for now */
511 fprintf(stderr
, "%s: drawable has no context!\n", __FUNCTION__
);
516 intelCopySubBuffer(__DRIdrawablePrivate
* dPriv
, int x
, int y
, int w
, int h
)
518 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
519 struct intel_context
*intel
=
520 (struct intel_context
*) dPriv
->driContextPriv
->driverPrivate
;
521 GLcontext
*ctx
= &intel
->ctx
;
523 if (ctx
->Visual
.doubleBufferMode
) {
524 drm_clip_rect_t rect
;
525 rect
.x1
= x
+ dPriv
->x
;
526 rect
.y1
= (dPriv
->h
- y
- h
) + dPriv
->y
;
527 rect
.x2
= rect
.x1
+ w
;
528 rect
.y2
= rect
.y1
+ h
;
529 _mesa_notifySwapBuffers(ctx
); /* flush pending rendering comands */
530 intelCopyBuffer(dPriv
, &rect
);
534 /* XXX this shouldn't be an error but we can't handle it for now */
535 fprintf(stderr
, "%s: drawable has no context!\n", __FUNCTION__
);
541 * Update the hardware state for drawing into a window or framebuffer object.
543 * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
544 * places within the driver.
546 * Basically, this needs to be called any time the current framebuffer
547 * changes, the renderbuffers change, or we need to draw into different
551 intel_draw_buffer(GLcontext
* ctx
, struct gl_framebuffer
*fb
)
553 struct intel_context
*intel
= intel_context(ctx
);
554 struct intel_region
*colorRegions
[MAX_DRAW_BUFFERS
], *depthRegion
= NULL
;
555 struct intel_renderbuffer
*irbDepth
= NULL
, *irbStencil
= NULL
;
558 /* this can happen during the initial context initialization */
562 /* Do this here, not core Mesa, since this function is called from
563 * many places within the driver.
565 if (ctx
->NewState
& (_NEW_BUFFERS
| _NEW_COLOR
| _NEW_PIXEL
)) {
566 /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
567 _mesa_update_framebuffer(ctx
);
568 /* this updates the DrawBuffer's Width/Height if it's a FBO */
569 _mesa_update_draw_buffer_bounds(ctx
);
572 if (fb
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
573 /* this may occur when we're called by glBindFrameBuffer() during
574 * the process of someone setting up renderbuffers, etc.
576 /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
581 * How many color buffers are we drawing into?
583 if (fb
->_NumColorDrawBuffers
== 0) {
585 colorRegions
[0] = NULL
;
586 intel
->constant_cliprect
= GL_TRUE
;
588 else if (fb
->_NumColorDrawBuffers
> 1) {
590 struct intel_renderbuffer
*irb
;
592 for (i
= 0; i
< fb
->_NumColorDrawBuffers
; i
++) {
593 irb
= intel_renderbuffer(fb
->_ColorDrawBuffers
[i
]);
594 colorRegions
[i
] = irb
? irb
->region
: NULL
;
596 intel
->constant_cliprect
= GL_TRUE
;
599 /* Get the intel_renderbuffer for the single colorbuffer we're drawing
600 * into, and set up cliprects if it's .
603 intel
->constant_cliprect
= intel
->driScreen
->dri2
.enabled
;
604 /* drawing to window system buffer */
605 if (fb
->_ColorDrawBufferIndexes
[0] == BUFFER_FRONT_LEFT
) {
606 if (!intel
->constant_cliprect
&& !intel
->front_cliprects
)
607 intel_batchbuffer_flush(intel
->batch
);
608 intel
->front_cliprects
= GL_TRUE
;
609 colorRegions
[0] = intel_get_rb_region(fb
, BUFFER_FRONT_LEFT
);
612 if (!intel
->constant_cliprect
&& intel
->front_cliprects
)
613 intel_batchbuffer_flush(intel
->batch
);
614 intel
->front_cliprects
= GL_FALSE
;
615 colorRegions
[0]= intel_get_rb_region(fb
, BUFFER_BACK_LEFT
);
619 /* drawing to user-created FBO */
620 struct intel_renderbuffer
*irb
;
621 irb
= intel_renderbuffer(fb
->_ColorDrawBuffers
[0]);
622 colorRegions
[0] = (irb
&& irb
->region
) ? irb
->region
: NULL
;
623 intel
->constant_cliprect
= GL_TRUE
;
627 if (!colorRegions
[0]) {
628 FALLBACK(intel
, INTEL_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
631 FALLBACK(intel
, INTEL_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
635 *** Get depth buffer region and check if we need a software fallback.
636 *** Note that the depth buffer is usually a DEPTH_STENCIL buffer.
638 if (fb
->_DepthBuffer
&& fb
->_DepthBuffer
->Wrapped
) {
639 irbDepth
= intel_renderbuffer(fb
->_DepthBuffer
->Wrapped
);
640 if (irbDepth
&& irbDepth
->region
) {
641 FALLBACK(intel
, INTEL_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
642 depthRegion
= irbDepth
->region
;
645 FALLBACK(intel
, INTEL_FALLBACK_DEPTH_BUFFER
, GL_TRUE
);
650 /* not using depth buffer */
651 FALLBACK(intel
, INTEL_FALLBACK_DEPTH_BUFFER
, GL_FALSE
);
657 *** This can only be hardware accelerated if we're using a
658 *** combined DEPTH_STENCIL buffer.
660 if (fb
->_StencilBuffer
&& fb
->_StencilBuffer
->Wrapped
) {
661 irbStencil
= intel_renderbuffer(fb
->_StencilBuffer
->Wrapped
);
662 if (irbStencil
&& irbStencil
->region
) {
663 ASSERT(irbStencil
->Base
._ActualFormat
== GL_DEPTH24_STENCIL8_EXT
);
664 FALLBACK(intel
, INTEL_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
667 FALLBACK(intel
, INTEL_FALLBACK_STENCIL_BUFFER
, GL_TRUE
);
671 /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */
672 FALLBACK(intel
, INTEL_FALLBACK_STENCIL_BUFFER
, GL_FALSE
);
676 * Update depth and stencil test state
678 if (ctx
->Driver
.Enable
) {
679 ctx
->Driver
.Enable(ctx
, GL_DEPTH_TEST
,
680 (ctx
->Depth
.Test
&& fb
->Visual
.depthBits
> 0));
681 ctx
->Driver
.Enable(ctx
, GL_STENCIL_TEST
,
682 (ctx
->Stencil
.Enabled
&& fb
->Visual
.stencilBits
> 0));
685 ctx
->NewState
|= (_NEW_DEPTH
| _NEW_STENCIL
);
688 intel
->vtbl
.set_draw_region(intel
, colorRegions
, depthRegion
,
689 fb
->_NumColorDrawBuffers
);
691 /* update viewport since it depends on window size */
692 if (ctx
->Driver
.Viewport
) {
693 ctx
->Driver
.Viewport(ctx
, ctx
->Viewport
.X
, ctx
->Viewport
.Y
,
694 ctx
->Viewport
.Width
, ctx
->Viewport
.Height
);
697 ctx
->NewState
|= _NEW_VIEWPORT
;
700 /* Set state we know depends on drawable parameters:
702 if (ctx
->Driver
.Scissor
)
703 ctx
->Driver
.Scissor(ctx
, ctx
->Scissor
.X
, ctx
->Scissor
.Y
,
704 ctx
->Scissor
.Width
, ctx
->Scissor
.Height
);
705 intel
->NewGLState
|= _NEW_SCISSOR
;
707 if (ctx
->Driver
.DepthRange
)
708 ctx
->Driver
.DepthRange(ctx
,
712 /* Update culling direction which changes depending on the
713 * orientation of the buffer:
715 if (ctx
->Driver
.FrontFace
)
716 ctx
->Driver
.FrontFace(ctx
, ctx
->Polygon
.FrontFace
);
718 ctx
->NewState
|= _NEW_POLYGON
;
723 intelDrawBuffer(GLcontext
* ctx
, GLenum mode
)
725 intel_draw_buffer(ctx
, ctx
->DrawBuffer
);
730 intelReadBuffer(GLcontext
* ctx
, GLenum mode
)
732 if (ctx
->ReadBuffer
== ctx
->DrawBuffer
) {
733 /* This will update FBO completeness status.
734 * A framebuffer will be incomplete if the GL_READ_BUFFER setting
735 * refers to a missing renderbuffer. Calling glReadBuffer can set
736 * that straight and can make the drawing buffer complete.
738 intel_draw_buffer(ctx
, ctx
->DrawBuffer
);
740 /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc)
741 * reference ctx->ReadBuffer and do appropriate state checks.
747 intelInitBufferFuncs(struct dd_function_table
*functions
)
749 functions
->Clear
= intelClear
;
750 functions
->DrawBuffer
= intelDrawBuffer
;
751 functions
->ReadBuffer
= intelReadBuffer
;