Esempio n. 1
0
File: blit.c Progetto: dumbbell/mesa
static GLboolean
compatible_resolve_formats(const struct gl_renderbuffer *readRb,
                           const struct gl_renderbuffer *drawRb)
{
   GLenum readFormat, drawFormat;

   /* The simple case where we know the backing Mesa formats are the same.
    */
   if (_mesa_get_srgb_format_linear(readRb->Format) ==
       _mesa_get_srgb_format_linear(drawRb->Format)) {
      return GL_TRUE;
   }

   /* The Mesa formats are different, so we must check whether the internal
    * formats are compatible.
    *
    * Under some circumstances, the user may request e.g. two GL_RGBA8
    * textures and get two entirely different Mesa formats like RGBA8888 and
    * ARGB8888. Drivers behaving like that should be able to cope with
    * non-matching formats by themselves, because it's not the user's fault.
    *
    * Blits between linear and sRGB formats are also allowed.
    */
   readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
   drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
   readFormat = _mesa_get_linear_internalformat(readFormat);
   drawFormat = _mesa_get_linear_internalformat(drawFormat);

   if (readFormat == drawFormat) {
      return GL_TRUE;
   }

   return GL_FALSE;
}
Esempio n. 2
0
File: blit.c Progetto: airlied/mesa
static GLboolean
compatible_resolve_formats(const struct gl_renderbuffer *readRb,
                           const struct gl_renderbuffer *drawRb)
{
   GLenum readFormat, drawFormat;

   /* This checks whether the internal formats are compatible rather than the
    * Mesa format for two reasons:
    *
    * • Under some circumstances, the user may request e.g. two GL_RGBA8
    *   textures and get two entirely different Mesa formats like RGBA8888 and
    *   ARGB8888. Drivers behaving like that should be able to cope with
    *   non-matching formats by themselves, because it's not the user's fault.
    *
    * • Picking two different internal formats can end up with the same Mesa
    *   format. For example the driver might be simulating GL_RGB textures
    *   with GL_RGBA internally and in that case both internal formats would
    *   end up with RGBA8888.
    *
    * This function is used to generate a GL error according to the spec so in
    * both cases we want to be looking at the application-level format, which
    * is InternalFormat.
    *
    * Blits between linear and sRGB formats are also allowed.
    */
   readFormat = _mesa_get_nongeneric_internalformat(readRb->InternalFormat);
   drawFormat = _mesa_get_nongeneric_internalformat(drawRb->InternalFormat);
   readFormat = _mesa_get_linear_internalformat(readFormat);
   drawFormat = _mesa_get_linear_internalformat(drawFormat);

   if (readFormat == drawFormat) {
      return GL_TRUE;
   }

   return GL_FALSE;
}
Esempio n. 3
0
/**
 * gl_renderbuffer::AllocStorage()
 * This is called to allocate the original drawing surface, and
 * during window resize.
 */
static GLboolean
st_renderbuffer_alloc_storage(struct gl_context * ctx,
                              struct gl_renderbuffer *rb,
                              GLenum internalFormat,
                              GLuint width, GLuint height)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = st->pipe->screen;
   struct st_renderbuffer *strb = st_renderbuffer(rb);
   enum pipe_format format = PIPE_FORMAT_NONE;
   struct pipe_surface surf_tmpl;
   struct pipe_resource templ;

   /* init renderbuffer fields */
   strb->Base.Width  = width;
   strb->Base.Height = height;
   strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
   strb->defined = GL_FALSE;  /* undefined contents now */

   if (strb->software) {
      return st_renderbuffer_alloc_sw_storage(ctx, rb, internalFormat,
                                              width, height);
   }

   /* Free the old surface and texture
    */
   pipe_surface_reference( &strb->surface, NULL );
   pipe_resource_reference( &strb->texture, NULL );

   /* If an sRGB framebuffer is unsupported, sRGB formats behave like linear
    * formats.
    */
   if (!ctx->Extensions.EXT_framebuffer_sRGB) {
      internalFormat = _mesa_get_linear_internalformat(internalFormat);
   }

   /* Handle multisample renderbuffers first.
    *
    * From ARB_framebuffer_object:
    *   If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero.
    *   Otherwise <samples> represents a request for a desired minimum
    *   number of samples. Since different implementations may support
    *   different sample counts for multisampled rendering, the actual
    *   number of samples allocated for the renderbuffer image is
    *   implementation dependent.  However, the resulting value for
    *   RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal
    *   to <samples> and no more than the next larger sample count supported
    *   by the implementation.
    *
    * So let's find the supported number of samples closest to NumSamples.
    * (NumSamples == 1) is treated the same as (NumSamples == 0).
    */
   if (rb->NumSamples > 1) {
      unsigned i;

      for (i = rb->NumSamples; i <= ctx->Const.MaxSamples; i++) {
         format = st_choose_renderbuffer_format(st, internalFormat, i);

         if (format != PIPE_FORMAT_NONE) {
            rb->NumSamples = i;
            break;
         }
      }
   } else {
      format = st_choose_renderbuffer_format(st, internalFormat, 0);
   }

   /* Not setting gl_renderbuffer::Format here will cause
    * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called.
    */
   if (format == PIPE_FORMAT_NONE) {
      return GL_TRUE;
   }

   strb->Base.Format = st_pipe_format_to_mesa_format(format);

   if (width == 0 || height == 0) {
      /* if size is zero, nothing to allocate */
      return GL_TRUE;
   }

   /* Setup new texture template.
    */
   memset(&templ, 0, sizeof(templ));
   templ.target = st->internal_target;
   templ.format = format;
   templ.width0 = width;
   templ.height0 = height;
   templ.depth0 = 1;
   templ.array_size = 1;
   templ.nr_samples = rb->NumSamples;
   if (util_format_is_depth_or_stencil(format)) {
      templ.bind = PIPE_BIND_DEPTH_STENCIL;
   }
   else if (strb->Base.Name != 0) {
      /* this is a user-created renderbuffer */
      templ.bind = PIPE_BIND_RENDER_TARGET;
   }
   else {
      /* this is a window-system buffer */
      templ.bind = (PIPE_BIND_DISPLAY_TARGET |
                    PIPE_BIND_RENDER_TARGET);
   }

   strb->texture = screen->resource_create(screen, &templ);

   if (!strb->texture)
      return FALSE;

   u_surface_default_template(&surf_tmpl, strb->texture);
   strb->surface = pipe->create_surface(pipe,
                                        strb->texture,
                                        &surf_tmpl);
   if (strb->surface) {
      assert(strb->surface->texture);
      assert(strb->surface->format);
      assert(strb->surface->width == width);
      assert(strb->surface->height == height);
   }

   return strb->surface != NULL;
}