コード例 #1
0
ファイル: brw_vtbl.c プロジェクト: VadimGirlin/mesa
/**
 * Update the hardware state for drawing into a window or framebuffer object.
 *
 * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
 * places within the driver.
 *
 * Basically, this needs to be called any time the current framebuffer
 * changes, the renderbuffers change, or we need to draw into different
 * color buffers.
 */
static void
brw_update_draw_buffer(struct intel_context *intel)
{
   struct gl_context *ctx = &intel->ctx;
   struct gl_framebuffer *fb = ctx->DrawBuffer;

   if (!fb) {
      /* this can happen during the initial context initialization */
      return;
   }

   /* 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);
      /* this updates the DrawBuffer's Width/Height if it's a FBO */
      _mesa_update_draw_buffer_bounds(ctx);
   }

   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;
   }

   /* Mesa's Stencil._Enabled field is updated when
    * _NEW_BUFFERS | _NEW_STENCIL, but i965 code assumes that the value
    * only changes with _NEW_STENCIL (which seems sensible).  So flag it
    * here since this is the _NEW_BUFFERS path.
    */
   intel->NewGLState |= (_NEW_DEPTH | _NEW_STENCIL);

   /* The driver uses this in places that need to look up
    * renderbuffers' buffer objects.
    */
   intel->NewGLState |= _NEW_BUFFERS;

   /* update viewport/scissor since it depends on window size */
   intel->NewGLState |= _NEW_VIEWPORT | _NEW_SCISSOR;

   /* Update culling direction which changes depending on the
    * orientation of the buffer:
    */
   intel->NewGLState |= _NEW_POLYGON;
}
コード例 #2
0
ファイル: blit.c プロジェクト: airlied/mesa
void
_mesa_blit_framebuffer(struct gl_context *ctx,
                       struct gl_framebuffer *readFb,
                       struct gl_framebuffer *drawFb,
                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                       GLbitfield mask, GLenum filter, const char *func)
{
   const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT |
                                     GL_DEPTH_BUFFER_BIT |
                                     GL_STENCIL_BUFFER_BIT);

   FLUSH_VERTICES(ctx, 0);

   /* Update completeness status of readFb and drawFb. */
   _mesa_update_framebuffer(ctx, readFb, drawFb);

   /* Make sure drawFb has an initialized bounding box. */
   _mesa_update_draw_buffer_bounds(ctx, drawFb);

   if (!readFb || !drawFb) {
      /* This will normally never happen but someday we may want to
       * support MakeCurrent() with no drawables.
       */
      return;
   }

   /* check for complete framebuffers */
   if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
       readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                  "%s(incomplete draw/read buffers)", func);
      return;
   }

   if (!is_valid_blit_filter(ctx, filter)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid filter %s)", func,
                  _mesa_enum_to_string(filter));
      return;
   }

   if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
        filter == GL_SCALED_RESOLVE_NICEST_EXT) &&
        (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s: invalid samples)", func,
                  _mesa_enum_to_string(filter));
      return;
   }

   if (mask & ~legalMaskBits) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid mask bits set)", func);
      return;
   }

   /* depth/stencil must be blitted with nearest filtering */
   if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
        && filter != GL_NEAREST) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
             "%s(depth/stencil requires GL_NEAREST filter)", func);
      return;
   }

   /* get color read/draw renderbuffers */
   if (mask & GL_COLOR_BUFFER_BIT) {
      const GLuint numColorDrawBuffers = drawFb->_NumColorDrawBuffers;
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
      const struct gl_renderbuffer *colorDrawRb = NULL;
      GLuint i;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if (!colorReadRb || numColorDrawBuffers == 0) {
         mask &= ~GL_COLOR_BUFFER_BIT;
      }
      else {
         for (i = 0; i < numColorDrawBuffers; i++) {
            colorDrawRb = drawFb->_ColorDrawBuffers[i];
            if (!colorDrawRb)
               continue;

            /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL
             * ES 3.0.1 spec says:
             *
             *     "If the source and destination buffers are identical, an
             *     INVALID_OPERATION error is generated. Different mipmap
             *     levels of a texture, different layers of a three-
             *     dimensional texture or two-dimensional array texture, and
             *     different faces of a cube map texture do not constitute
             *     identical buffers."
             */
            if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(source and destination color "
                           "buffer cannot be the same)", func);
               return;
            }

            if (!compatible_color_datatypes(colorReadRb->Format,
                                            colorDrawRb->Format)) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(color buffer datatypes mismatch)", func);
               return;
            }
            /* extra checks for multisample copies... */
            if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
               /* color formats must match on GLES. This isn't checked on
                * desktop GL because the GL 4.4 spec was changed to allow it.
                * In the section entitled “Changes in the released
                * Specification of July 22, 2013” it says:
                *
                * “Relax BlitFramebuffer in section 18.3.1 so that format
                *  conversion can take place during multisample blits, since
                *  drivers already allow this and some apps depend on it.”
                */
               if (_mesa_is_gles(ctx) &&
                   !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
                  _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(bad src/dst multisample pixel formats)", func);
                  return;
               }
            }
         }
         if (filter != GL_NEAREST) {
            /* From EXT_framebuffer_multisample_blit_scaled specification:
             * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
             * if filter is not NEAREST and read buffer contains integer data."
             */
            GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
            if (type == GL_INT || type == GL_UNSIGNED_INT) {
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "%s(integer color type)", func);
               return;
            }
         }
      }
   }

   if (mask & GL_STENCIL_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_STENCIL].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_STENCIL].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_STENCIL_BUFFER_BIT;
      }
      else {
         int read_z_bits, draw_z_bits;

         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(source and destination stencil "
                        "buffer cannot be the same)", func);
            return;
         }

         if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
             _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
            /* There is no need to check the stencil datatype here, because
             * there is only one: GL_UNSIGNED_INT.
             */
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(stencil attachment format mismatch)", func);
            return;
         }

         read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
         draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);

         /* If both buffers also have depth data, the depth formats must match
          * as well.  If one doesn't have depth, it's not blitted, so we should
          * ignore the depth format check.
          */
         if (read_z_bits > 0 && draw_z_bits > 0 &&
             (read_z_bits != draw_z_bits ||
              _mesa_get_format_datatype(readRb->Format) !=
              _mesa_get_format_datatype(drawRb->Format))) {

            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(stencil attachment depth format mismatch)", func);
            return;
         }
      }
   }

   if (mask & GL_DEPTH_BUFFER_BIT) {
      struct gl_renderbuffer *readRb =
         readFb->Attachment[BUFFER_DEPTH].Renderbuffer;
      struct gl_renderbuffer *drawRb =
         drawFb->Attachment[BUFFER_DEPTH].Renderbuffer;

      /* From the EXT_framebuffer_object spec:
       *
       *     "If a buffer is specified in <mask> and does not exist in both
       *     the read and draw framebuffers, the corresponding bit is silently
       *     ignored."
       */
      if ((readRb == NULL) || (drawRb == NULL)) {
         mask &= ~GL_DEPTH_BUFFER_BIT;
      }
      else {
         int read_s_bit, draw_s_bit;

         if (_mesa_is_gles3(ctx) && (drawRb == readRb)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(source and destination depth "
                        "buffer cannot be the same)", func);
            return;
         }

         if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
              _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
             (_mesa_get_format_datatype(readRb->Format) !=
              _mesa_get_format_datatype(drawRb->Format))) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(depth attachment format mismatch)", func);
            return;
         }

         read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
         draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);

         /* If both buffers also have stencil data, the stencil formats must
          * match as well.  If one doesn't have stencil, it's not blitted, so
          * we should ignore the stencil format check.
          */
         if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(depth attachment stencil bits mismatch)", func);
            return;
         }
      }
   }


   if (_mesa_is_gles3(ctx)) {
      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
       * 3.0.1 spec says:
       *
       *     "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero,
       *     an INVALID_OPERATION error is generated."
       */
      if (drawFb->Visual.samples > 0) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(destination samples must be 0)", func);
         return;
      }

      /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES
       * 3.0.1 spec says:
       *
       *     "If SAMPLE_BUFFERS for the read framebuffer is greater than zero,
       *     no copy is performed and an INVALID_OPERATION error is generated
       *     if the formats of the read and draw framebuffers are not
       *     identical or if the source and destination rectangles are not
       *     defined with the same (X0, Y0) and (X1, Y1) bounds."
       *
       * The format check was made above because desktop OpenGL has the same
       * requirement.
       */
      if (readFb->Visual.samples > 0
          && (srcX0 != dstX0 || srcY0 != dstY0
              || srcX1 != dstX1 || srcY1 != dstY1)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(bad src/dst multisample region)", func);
         return;
      }
   } else {
      if (readFb->Visual.samples > 0 &&
          drawFb->Visual.samples > 0 &&
          readFb->Visual.samples != drawFb->Visual.samples) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(mismatched samples)", func);
         return;
      }

      /* extra checks for multisample copies... */
      if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) &&
          (filter == GL_NEAREST || filter == GL_LINEAR)) {
         /* src and dest region sizes must be the same */
         if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) ||
             abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "%s(bad src/dst multisample region sizes)", func);
            return;
         }
      }
   }

   /* Debug code */
   if (DEBUG_BLIT) {
      const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
      const struct gl_renderbuffer *colorDrawRb = NULL;
      GLuint i = 0;

      printf("%s(%d, %d, %d, %d,  %d, %d, %d, %d,"
             " 0x%x, 0x%x)\n", func,
             srcX0, srcY0, srcX1, srcY1,
             dstX0, dstY0, dstX1, dstY1,
             mask, filter);

      if (colorReadRb) {
         const struct gl_renderbuffer_attachment *att;

         att = find_attachment(readFb, colorReadRb);
         printf("  Src FBO %u  RB %u (%dx%d)  ",
                readFb->Name, colorReadRb->Name,
                colorReadRb->Width, colorReadRb->Height);
         if (att && att->Texture) {
            printf("Tex %u  tgt 0x%x  level %u  face %u",
                   att->Texture->Name,
                   att->Texture->Target,
                   att->TextureLevel,
                   att->CubeMapFace);
         }
         printf("\n");

         /* Print all active color render buffers */
         for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
            colorDrawRb = drawFb->_ColorDrawBuffers[i];
            if (!colorDrawRb)
               continue;

            att = find_attachment(drawFb, colorDrawRb);
            printf("  Dst FBO %u  RB %u (%dx%d)  ",
                   drawFb->Name, colorDrawRb->Name,
                   colorDrawRb->Width, colorDrawRb->Height);
            if (att && att->Texture) {
               printf("Tex %u  tgt 0x%x  level %u  face %u",
                      att->Texture->Name,
                      att->Texture->Target,
                      att->TextureLevel,
                      att->CubeMapFace);
            }
            printf("\n");
         }
      }
   }

   if (!mask ||
       (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 ||
       (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) {
      return;
   }

   assert(ctx->Driver.BlitFramebuffer);
   ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb,
                               srcX0, srcY0, srcX1, srcY1,
                               dstX0, dstY0, dstX1, dstY1,
                               mask, filter);
}
コード例 #3
0
ファイル: state.c プロジェクト: aljen/haiku-opengl
/**
 * Compute derived GL state.
 * If __GLcontextRec::NewState is non-zero then this function \b must
 * be called before rendering anything.
 *
 * Calls dd_function_table::UpdateState to perform any internal state
 * management necessary.
 * 
 * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
 * _mesa_update_buffer_bounds(),
 * _mesa_update_lighting() and _mesa_update_tnl_spaces().
 */
void
_mesa_update_state_locked( GLcontext *ctx )
{
   GLbitfield new_state = ctx->NewState;
   GLbitfield prog_flags = _NEW_PROGRAM;
   GLbitfield new_prog_state = 0x0;

   if (new_state == _NEW_CURRENT_ATTRIB) 
      goto out;

   if (MESA_VERBOSE & VERBOSE_STATE)
      _mesa_print_state("_mesa_update_state", new_state);

   /* Determine which state flags effect vertex/fragment program state */
   if (ctx->FragmentProgram._MaintainTexEnvProgram) {
      prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR |
		     _NEW_ARRAY);
   }
   if (ctx->VertexProgram._MaintainTnlProgram) {
      prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
                     _NEW_TRANSFORM | _NEW_POINT |
                     _NEW_FOG | _NEW_LIGHT |
                     _MESA_NEW_NEED_EYE_COORDS);
   }

   /*
    * Now update derived state info
    */

   if (new_state & prog_flags)
      update_program_enables( ctx );

   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
      _mesa_update_modelview_project( ctx, new_state );

   if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
      _mesa_update_texture( ctx, new_state );

   if (new_state & _NEW_BUFFERS)
      _mesa_update_framebuffer(ctx);

   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
      _mesa_update_draw_buffer_bounds( ctx );

   if (new_state & _NEW_POLYGON)
      update_polygon( ctx );

   if (new_state & _NEW_LIGHT)
      _mesa_update_lighting( ctx );

   if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
      _mesa_update_stencil( ctx );

#if FEATURE_pixel_transfer
   if (new_state & _MESA_NEW_TRANSFER_STATE)
      _mesa_update_pixel( ctx, new_state );
#endif

   if (new_state & _DD_NEW_SEPARATE_SPECULAR)
      update_separate_specular( ctx );

   if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT))
      update_arrays( ctx );

   if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT))
      update_viewport_matrix(ctx);

   if (new_state & _NEW_MULTISAMPLE)
      update_multisample( ctx );

   if (new_state & _NEW_COLOR)
      update_color( ctx );

#if 0
   if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT
                    | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
      update_tricaps( ctx, new_state );
#endif

   /* ctx->_NeedEyeCoords is now up to date.
    *
    * If the truth value of this variable has changed, update for the
    * new lighting space and recompute the positions of lights and the
    * normal transform.
    *
    * If the lighting space hasn't changed, may still need to recompute
    * light positions & normal transforms for other reasons.
    */
   if (new_state & _MESA_NEW_NEED_EYE_COORDS) 
      _mesa_update_tnl_spaces( ctx, new_state );

   if (new_state & prog_flags) {
      /* When we generate programs from fixed-function vertex/fragment state
       * this call may generate/bind a new program.  If so, we need to
       * propogate the _NEW_PROGRAM flag to the driver.
       */
      new_prog_state |= update_program( ctx );
   }


 out:
   new_prog_state |= update_program_constants(ctx);

   /*
    * Give the driver a chance to act upon the new_state flags.
    * The driver might plug in different span functions, for example.
    * Also, this is where the driver can invalidate the state of any
    * active modules (such as swrast_setup, swrast, tnl, etc).
    *
    * Set ctx->NewState to zero to avoid recursion if
    * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
    */
   new_state = ctx->NewState | new_prog_state;
   ctx->NewState = 0;
   ctx->Driver.UpdateState(ctx, new_state);
   ctx->Array.NewState = 0;
}
コード例 #4
0
/**
 * Update the hardware state for drawing into a window or framebuffer object.
 *
 * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
 * places within the driver.
 *
 * Basically, this needs to be called any time the current framebuffer
 * changes, the renderbuffers change, or we need to draw into different
 * color buffers.
 */
void
intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
{
   struct intel_context *intel = intel_context(ctx);
   struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;
   struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;

   if (!fb) {
      /* this can happen during the initial context initialization */
      return;
   }

   /* 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);
      /* this updates the DrawBuffer's Width/Height if it's a FBO */
      _mesa_update_draw_buffer_bounds(ctx);
   }

   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 are zero buffers or the buffer is too big, don't configure any
    * regions for hardware drawing.  We'll fallback to software below.  Not
    * having regions set makes some of the software fallback paths faster.
    */
   if ((fb->Width > ctx->Const.MaxRenderbufferSize)
       || (fb->Height > ctx->Const.MaxRenderbufferSize)
       || (fb->_NumColorDrawBuffers == 0)) {
      /* writing to 0  */
      colorRegions[0] = NULL;
   }
   else if (fb->_NumColorDrawBuffers > 1) {
       int i;
       struct intel_renderbuffer *irb;

       for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
           irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
           colorRegions[i] = irb ? irb->region : NULL;
       }
   }
   else {
      /* Get the intel_renderbuffer for the single colorbuffer we're drawing
       * into.
       */
      if (fb->Name == 0) {
	 /* drawing to window system buffer */
	 if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT)
	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
	 else
	    colorRegions[0] = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
      }
      else {
	 /* drawing to user-created FBO */
	 struct intel_renderbuffer *irb;
	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
	 colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
      }
   }

   if (!colorRegions[0]) {
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
   }
   else {
      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
   }

   /***
    *** Get depth buffer region and check if we need a software fallback.
    *** Note that the depth buffer is usually a DEPTH_STENCIL buffer.
    ***/
   if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
      irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
      if (irbDepth && irbDepth->region) {
         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
         depthRegion = irbDepth->region;
      }
      else {
         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
         depthRegion = NULL;
      }
   }
   else {
      /* not using depth buffer */
      FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
      depthRegion = NULL;
   }

   /***
    *** Stencil buffer
    *** This can only be hardware accelerated if we're using a
    *** combined DEPTH_STENCIL buffer.
    ***/
   if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
      irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
      if (irbStencil && irbStencil->region) {
         ASSERT(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
      }
      else {
         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
      }
   }
   else {
      /* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */
      FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_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->region)
      depthRegion = irbStencil->region;

   /*
    * Update depth and stencil test state
    */
   if (ctx->Driver.Enable) {
      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 {
      /* Mesa's Stencil._Enabled field is updated when
       * _NEW_BUFFERS | _NEW_STENCIL, but i965 code assumes that the value
       * only changes with _NEW_STENCIL (which seems sensible).  So flag it
       * here since this is the _NEW_BUFFERS path.
       */
      intel->NewGLState |= (_NEW_DEPTH | _NEW_STENCIL);
   }

   intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, 
                               fb->_NumColorDrawBuffers);
   intel->NewGLState |= _NEW_BUFFERS;

   /* update viewport since it depends on window size */
#ifdef I915
   intelCalcViewport(ctx);
#else
   intel->NewGLState |= _NEW_VIEWPORT;
#endif
   /* Set state we know depends on drawable parameters:
    */
   if (ctx->Driver.Scissor)
      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			  ctx->Scissor.Width, ctx->Scissor.Height);
   intel->NewGLState |= _NEW_SCISSOR;

   if (ctx->Driver.DepthRange)
      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
      intel->NewGLState |= _NEW_POLYGON;
}
コード例 #5
0
ファイル: state.c プロジェクト: ChristophHaag/mesa-mesa
/**
 * Compute derived GL state.
 * If __struct gl_contextRec::NewState is non-zero then this function \b must
 * be called before rendering anything.
 *
 * Calls dd_function_table::UpdateState to perform any internal state
 * management necessary.
 * 
 * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
 * _mesa_update_buffer_bounds(),
 * _mesa_update_lighting() and _mesa_update_tnl_spaces().
 */
void
_mesa_update_state_locked( struct gl_context *ctx )
{
   GLbitfield new_state = ctx->NewState;
   GLbitfield new_prog_state = 0x0;
   const GLbitfield computed_states = ~(_NEW_CURRENT_ATTRIB | _NEW_LINE);

   /* we can skip a bunch of state validation checks if the dirty
    * state matches one or more bits in 'computed_states'.
    */
   if ((new_state & computed_states) == 0)
      goto out;

   if (MESA_VERBOSE & VERBOSE_STATE)
      _mesa_print_state("_mesa_update_state", new_state);

   if (new_state & _NEW_BUFFERS)
      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);

   /* Handle Core and Compatibility contexts separately. */
   if (ctx->API == API_OPENGL_COMPAT ||
       ctx->API == API_OPENGLES) {
      GLbitfield prog_flags = _NEW_PROGRAM;

      /* Determine which state flags effect vertex/fragment program state */
      if (ctx->FragmentProgram._MaintainTexEnvProgram) {
         prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE_OBJECT | _NEW_FOG |
                        _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
                        _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
                        _NEW_COLOR | _NEW_TEXTURE_STATE);
      }
      if (ctx->VertexProgram._MaintainTnlProgram) {
         prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE_OBJECT |
                        _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
                        _NEW_FOG | _NEW_LIGHT | _NEW_TEXTURE_STATE |
                        _MESA_NEW_NEED_EYE_COORDS);
      }

      /*
       * Now update derived state info
       */
      if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
         _mesa_update_modelview_project( ctx, new_state );

      if (new_state & _NEW_TEXTURE_MATRIX)
         _mesa_update_texture_matrices(ctx);

      if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | _NEW_PROGRAM))
         _mesa_update_texture_state(ctx);

      if (new_state & _NEW_LIGHT)
         _mesa_update_lighting(ctx);

      if (new_state & _NEW_PIXEL)
         _mesa_update_pixel( ctx );

      /* ctx->_NeedEyeCoords is now up to date.
       *
       * If the truth value of this variable has changed, update for the
       * new lighting space and recompute the positions of lights and the
       * normal transform.
       *
       * If the lighting space hasn't changed, may still need to recompute
       * light positions & normal transforms for other reasons.
       */
      if (new_state & _MESA_NEW_NEED_EYE_COORDS)
         _mesa_update_tnl_spaces( ctx, new_state );

      if (new_state & prog_flags) {
         /* When we generate programs from fixed-function vertex/fragment state
          * this call may generate/bind a new program.  If so, we need to
          * propogate the _NEW_PROGRAM flag to the driver.
          */
         new_prog_state |= update_program(ctx);
      }
   } else {
      /* GL Core and GLES 2/3 contexts */
      if (new_state & (_NEW_TEXTURE_OBJECT | _NEW_PROGRAM))
         _mesa_update_texture_state(ctx);

      if (new_state & _NEW_PROGRAM)
         update_program(ctx);
   }

 out:
   new_prog_state |= update_program_constants(ctx);

   ctx->NewState |= new_prog_state;
   vbo_exec_invalidate_state(ctx);

   /*
    * Give the driver a chance to act upon the new_state flags.
    * The driver might plug in different span functions, for example.
    * Also, this is where the driver can invalidate the state of any
    * active modules (such as swrast_setup, swrast, tnl, etc).
    */
   ctx->Driver.UpdateState(ctx);
   ctx->NewState = 0;
}
コード例 #6
0
ファイル: state.c プロジェクト: airlied/mesa
/**
 * Compute derived GL state.
 * If __struct gl_contextRec::NewState is non-zero then this function \b must
 * be called before rendering anything.
 *
 * Calls dd_function_table::UpdateState to perform any internal state
 * management necessary.
 * 
 * \sa _mesa_update_modelview_project(), _mesa_update_texture(),
 * _mesa_update_buffer_bounds(),
 * _mesa_update_lighting() and _mesa_update_tnl_spaces().
 */
void
_mesa_update_state_locked( struct gl_context *ctx )
{
   GLbitfield new_state = ctx->NewState;
   GLbitfield prog_flags = _NEW_PROGRAM;
   GLbitfield new_prog_state = 0x0;
   const GLbitfield computed_states = ~(_NEW_CURRENT_ATTRIB | _NEW_LINE);

   /* we can skip a bunch of state validation checks if the dirty
    * state matches one or more bits in 'computed_states'.
    */
   if ((new_state & computed_states) == 0)
      goto out;

   if (MESA_VERBOSE & VERBOSE_STATE)
      _mesa_print_state("_mesa_update_state", new_state);

   /* Determine which state flags effect vertex/fragment program state */
   if (ctx->FragmentProgram._MaintainTexEnvProgram) {
      prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
		     _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT |
		     _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP |
		     _NEW_COLOR);
   }
   if (ctx->VertexProgram._MaintainTnlProgram) {
      prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE |
                     _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT |
                     _NEW_FOG | _NEW_LIGHT |
                     _MESA_NEW_NEED_EYE_COORDS);
   }

   /*
    * Now update derived state info
    */

   if (new_state & prog_flags)
      update_program_enables( ctx );

   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
      _mesa_update_modelview_project( ctx, new_state );

   if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX))
      _mesa_update_texture( ctx, new_state );

   if (new_state & _NEW_POLYGON)
      update_frontbit( ctx );

   if (new_state & _NEW_BUFFERS)
      _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer);

   if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT))
      _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);

   if (new_state & _NEW_LIGHT)
      _mesa_update_lighting( ctx );

   if (new_state & (_NEW_LIGHT | _NEW_PROGRAM))
      update_twoside( ctx );

   if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
      _mesa_update_stencil( ctx );

   if (new_state & _NEW_PIXEL)
      _mesa_update_pixel( ctx, new_state );

   /* ctx->_NeedEyeCoords is now up to date.
    *
    * If the truth value of this variable has changed, update for the
    * new lighting space and recompute the positions of lights and the
    * normal transform.
    *
    * If the lighting space hasn't changed, may still need to recompute
    * light positions & normal transforms for other reasons.
    */
   if (new_state & _MESA_NEW_NEED_EYE_COORDS) 
      _mesa_update_tnl_spaces( ctx, new_state );

   if (new_state & prog_flags) {
      /* When we generate programs from fixed-function vertex/fragment state
       * this call may generate/bind a new program.  If so, we need to
       * propogate the _NEW_PROGRAM flag to the driver.
       */
      new_prog_state |= update_program( ctx );
   }

   if (new_state & _NEW_ARRAY)
      _mesa_update_vao_client_arrays(ctx, ctx->Array.VAO);

 out:
   new_prog_state |= update_program_constants(ctx);

   /*
    * Give the driver a chance to act upon the new_state flags.
    * The driver might plug in different span functions, for example.
    * Also, this is where the driver can invalidate the state of any
    * active modules (such as swrast_setup, swrast, tnl, etc).
    *
    * Set ctx->NewState to zero to avoid recursion if
    * Driver.UpdateState() has to call FLUSH_VERTICES().  (fixed?)
    */
   new_state = ctx->NewState | new_prog_state;
   ctx->NewState = 0;
   ctx->Driver.UpdateState(ctx, new_state);
   ctx->Array.VAO->NewArrays = 0x0;
}