+ /* Do this here, not core Mesa, since this function is called from
+ * many places within the driver.
+ */
+ if (ctx->NewState & _NEW_BUFFERS) {
+ /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
+ _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
+ }
+
+ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ /* this may occur when we're called by glBindFrameBuffer() during
+ * the process of someone setting up renderbuffers, etc.
+ */
+ /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
+ return;
+ }
+
+ /* How many color buffers are we drawing into?
+ *
+ * If there is more than one drawbuffer (GL_FRONT_AND_BACK), or the
+ * drawbuffers are too big, we have to fallback to software.
+ */
+ if ((fb->Width > ctx->Const.MaxRenderbufferSize)
+ || (fb->Height > ctx->Const.MaxRenderbufferSize)) {
+ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, true);
+ } else if (fb->_NumColorDrawBuffers > 1) {
+ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, true);
+ } else {
+ struct intel_renderbuffer *irb;
+ irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
+ colorRegion = (irb && irb->mt) ? irb->mt->region : NULL;
+ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, false);
+ }
+
+ /* Check for depth fallback. */
+ if (irbDepth && irbDepth->mt) {
+ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, false);
+ depthRegion = irbDepth->mt->region;
+ } else if (irbDepth && !irbDepth->mt) {
+ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, true);
+ depthRegion = NULL;
+ } else { /* !irbDepth */
+ /* No fallback is needed because there is no depth buffer. */
+ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, false);
+ depthRegion = NULL;
+ }
+
+ /* Check for stencil fallback. */
+ if (irbStencil && irbStencil->mt) {
+ assert(intel_rb_format(irbStencil) == MESA_FORMAT_Z24_UNORM_S8_UINT);
+ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, false);
+ } else if (irbStencil && !irbStencil->mt) {
+ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, true);
+ } else { /* !irbStencil */
+ /* No fallback is needed because there is no stencil buffer. */
+ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, false);
+ }
+
+ /* If we have a (packed) stencil buffer attached but no depth buffer,
+ * we still need to set up the shared depth/stencil state so we can use it.
+ */
+ if (depthRegion == NULL && irbStencil && irbStencil->mt
+ && intel_rb_format(irbStencil) == MESA_FORMAT_Z24_UNORM_S8_UINT) {
+ depthRegion = irbStencil->mt->region;
+ }
+
+ /*
+ * Update depth and stencil test state
+ */
+ ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
+ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
+
+ i915_update_color_write_enable(i915, colorRegion != NULL);
+
+ intel->vtbl.set_draw_region(intel, &colorRegion, depthRegion,
+ fb->_NumColorDrawBuffers);
+ intel->NewGLState |= _NEW_BUFFERS;
+
+ /* Set state we know depends on drawable parameters:
+ */
+ intelCalcViewport(ctx);
+ ctx->Driver.Scissor(ctx);
+
+ /* Update culling direction which changes depending on the
+ * orientation of the buffer:
+ */
+ ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
+}